Algorithm C/C++/Java/C#:帮助解析数字
我有一个真正的问题(这不是家庭作业,你可以查看我的个人资料)。我需要解析格式不受我控制的数据 数据如下所示: 6852:6100752 首先是一个9位数的数字,后面是冒号 然后我确定,在冒号之后:Algorithm C/C++/Java/C#:帮助解析数字,algorithm,Algorithm,我有一个真正的问题(这不是家庭作业,你可以查看我的个人资料)。我需要解析格式不受我控制的数据 数据如下所示: 6852:6100752 首先是一个9位数的数字,后面是冒号 然后我确定,在冒号之后: 至少有一个有效的数字组合与列前的数字相加 我确切地知道冒号前的数字加起来有多少(在本例中为两个,但可能高达十个) 在这种情况下,6852是6100+752 我的问题是:我需要找到这些数字(在本例中为6100+752) 不幸的是,在我被迫解析的数据中,数字之间的分隔符(逗号)也是数字本身内部使用的分
- 至少有一个有效的数字组合与列前的数字相加
- 我确切地知道冒号前的数字加起来有多少(在本例中为两个,但可能高达十个)
您通常如何用C风格的括号语言解决此类问题?我认为您的主要问题是决定如何实际解析数字。剩下的只是死记硬背地处理字符串->数字和组合上的迭代 例如,在您给出的示例中,您可以试探性地确定一个单位数字后跟一个三位数字实际上是一个四位数字。像这样的启发式在更大的数据集上是否成立?如果不是,您还可能需要迭代可能的输入解析组合,这意味着原始解决方案将具有很大的多项式复杂性(O(nx),其中x大于4) 实际上,使用递归搜索很容易检查哪些数字相加
List<int> GetSummands(int total, int numberOfElements, IEnumerable<int> values)
{
if (numberOfElements == 0)
{
if (total == 0)
return new List<int>(); // Empty list.
else
return null; // Indicate no solution.
}
else if (total < 0)
{
return null; // Indicate no solution.
}
else
{
for (int i = 0; i < values.Count; ++i)
{
List<int> summands = GetSummands(
total - values[i], numberOfElements - 1, values.Skip(i + 1));
if (summands != null)
{
// Found solution.
summands.Add(values[i]);
return summands;
}
}
}
}
列出GetSummand(int total、int numberOfElements、IEnumerable值)
{
if(numberOfElements==0)
{
如果(总计==0)
返回新列表();//空列表。
其他的
返回null;//表示没有解决方案。
}
否则如果(总数<0)
{
返回null;//表示没有解决方案。
}
其他的
{
对于(int i=0;i
我认为您的主要问题是决定如何实际解析数字。剩下的只是死记硬背地处理字符串->数字和组合上的迭代
例如,在您给出的示例中,您可以试探性地确定一个单位数字后跟一个三位数字实际上是一个四位数字。像这样的启发式在更大的数据集上是否成立?如果不是,您还可能需要迭代可能的输入解析组合,这意味着原始解决方案将具有很大的多项式复杂性(O(nx),其中x大于4)
实际上,使用递归搜索很容易检查哪些数字相加
List<int> GetSummands(int total, int numberOfElements, IEnumerable<int> values)
{
if (numberOfElements == 0)
{
if (total == 0)
return new List<int>(); // Empty list.
else
return null; // Indicate no solution.
}
else if (total < 0)
{
return null; // Indicate no solution.
}
else
{
for (int i = 0; i < values.Count; ++i)
{
List<int> summands = GetSummands(
total - values[i], numberOfElements - 1, values.Skip(i + 1));
if (summands != null)
{
// Found solution.
summands.Add(values[i]);
return summands;
}
}
}
}
列出GetSummand(int total、int numberOfElements、IEnumerable值)
{
if(numberOfElements==0)
{
如果(总计==0)
返回新列表();//空列表。
其他的
返回null;//表示没有解决方案。
}
否则如果(总数<0)
{
返回null;//表示没有解决方案。
}
其他的
{
对于(int i=0;i
我认为您应该尝试所有可能的方法来解析字符串并计算总和,然后返回给出正确总和的结果列表。在大多数情况下,这应该只是一个结果,除非你非常不走运
需要注意的一点是,如果
aa,bbb
和bbb
正好是3位数字,则只会出现歧义。如果你有aa,bb,只有一种方法可以解析它。我认为你应该尝试所有可能的方法来解析字符串,计算总和,并返回一个给出正确总和的结果列表。在大多数情况下,这应该只是一个结果,除非你非常不走运
需要注意的一点是,如果
aa,bbb
和bbb
正好是3位数字,则只会出现歧义。如果你有aa,bb,只有一种方法可以解析它。好吧,我会从蛮力方法开始,然后应用一些启发式方法来修剪搜索空间。只需将右边的列表用逗号分开,并迭代所有可能的方法将它们分组为n个术语(其中n是解决方案中的术语数)。您可以使用以下两条规则跳过无效的可能性
(1) 您知道,任何一组1或2位数字都必须以一个术语开头
(2) 您知道,逗号分隔列表中的候选项不能大于左侧的总数。(这还告诉您任何候选词可以拥有的最大数字组数。)好吧,我将从蛮力方法开始,然后应用一些启发式方法来修剪搜索空间。只需将右边的列表用逗号分开,并在所有pos上迭代即可
int total; // The total read before the colon
// Takes the list of tokens as integers after the colon
// tokens is the set of tokens left to analyse,
// partialList is the partial list of numbers built so far
// sum is the sum of numbers in partialList
// Aggregate takes 2 ints XXX and YYY and returns XXX,YYY (= XXX*1000+YYY)
function getNumbers(tokens, sum, partialList) =
if isEmpty(tokens)
if sum = total return partialList
else return null // Got to the end with the wrong sum
var result1 = getNumbers(tokens[1:end], sum+token[0], Add(partialList, tokens[0]))
var result2 = getNumbers(tokens[2:end], sum+Aggregate(token[0], token[1]), Append(partialList, Aggregate(tokens[0], tokens[1])))
if result1 <> null return result1
if result2 <> null return result2
return null // No solution overall