我有一个包含整数的字符串(按降序),然后输出应该是空格分隔的整数。整数不是负数。
INPUT: constructor chain
输出 9876543
INPUT: 9 8 7 6 5 4 3
输出 109876543
INPUT: 10 9 8 7 6 5 4 3
输出 400399398397
所以我尝试使用400 399 398 397
,但无法获得所需的结果,这是我尝试过的代码:
sscanf()
如何达到预期效果?
答案 0 :(得分:1)
继续注释和附加答案,将字符串解析并分隔成一个空格分隔的整数递减1,可能有许多不同的方法可以采用。最大的设计问题是,您是从输入字符串的长度开始,将其切成两半然后向后工作,将您检查相邻值的位数减少一个 - 或者是否从头开始并向最后工作增加沿途考虑的位数。
无论您选择何种方向,扭曲都是处理/检查具有不同位数的相邻值。您的第二个示例109876543
触及了这个转折的核心,您必须编写一种方法来检查下一个单的 2位值10
系列9
中的-digit 值。没有很好的方法可以做到这一点。一种合理的方法是简单地计算可由n
- 数字(例如10, 100, 1000, ...
)表示的最小数字。基本上10^(n-1)
(我们让int expn = n - 1;
)。如果您的第一个值v1
等于10^(n-1)
,则减少您为下一个最小值考虑的字符数。如下所示:
while (expn--) /* loop to build 10 ^ (n-1) */
x10 *= 10; /* compute 10 ^ (n-1), 10, 100 */
if (v1 == x10) /* compare against v1 */
n--; /* reduce t2 by 1-char/digit */
该任务的其余部分基本上是一个强力检查,其中包含保护数组边界所需的最少验证次数,同时处理向整数数组添加值(或者您希望存储值,直到您验证或使剩余的值无效为止当你在剩余的角色中工作时,字符串中的字符。
将所有部分组合在一起,并注意到有许多方法可以对此进行编码,此示例只有一个,您可以执行与以下类似的操作。请注意,代码只是通过从字符值中减去int
来处理从单位数系列案例中的ASCII到'0'
的转换,对于多位数转换,strtol
用于errno
的验证检查。代码从字符串的开头到结尾起作用,递增检查的数字,直到到达字符串的结尾。如果找到解,则输出以空格分隔的整数列表,否则输出"no solution found."
。代码已注释,以帮助您工作。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define MAXI 256
int main (int argc, char **argv) {
int a[MAXI] = {0}, i = 1, idx = 0, n = 1, len;
char *p = argc > 1 ? argv[1] : "9876543";
printf ("string : %s\n", p); /* original input string */
len = (int)strlen (p); /* get length */
while (i + n <= len && n < len) { /* loop until conditions met */
if (n >= MAXI) { /* protect int array bounds */
fprintf (stderr, "warning: array full, %d elements filled.\n", n);
break;
}
if (n == 1) { /* handle single digits series */
if (p[i - 1] == p[i] + 1) { /* previous equal current + 1? */
if (!idx) /* if array index == 0 */
a[idx++] = p[i - 1] - '0'; /* store first integer */
a[idx++] = p[i] - '0'; /* store current integer */
i++; /* increment string index */
}
else
n++, i = n, idx = 0; /* increment n-digits to check */
} /* set i = n, zero array index */
else { /* handle multi-digit values */
char t1[MAXI] = "", t2[MAXI] = ""; /* tmp strings for values */
int v1 = 0, v2 = 0, /* tmp for coverted values */
expn = n - 1, x10 = 1, /* 10 ^ expn for n-- test */
norig = n; /* n to restore on no match */
strncpy (t1, p + i - n, n); /* copy n-digits for 1st value */
errno = 0;
v1 = (int) strtol (t1, NULL, 10); /* convert to int/validate */
if (errno) {
fprintf (stderr, "error: failed conversion, i: %d, n: %d\n",
i, n);
return 1;
}
while (expn--) /* loop to build 10 ^ (n-1) */
x10 *= 10; /* compute 10 ^ (n-1), 10, 100 */
if (v1 == x10) /* compare against v1 */
n--; /* reduce t2 by 1-char/digit */
strncpy (t2, p + i, n); /* copy n-digits for 2nd value */
errno = 0;
v2 = (int) strtol (t2, NULL, 10); /* convert to int/validate */
if (errno) {
fprintf (stderr, "error: failed conversion, i: %d, n: %d\n",
i, n);
return 1;
}
if (v1 == v2 + 1) { /* check decreasing values */
if (!idx) /* if array index == 0 */
a[idx++] = v1; /* store first integer */
a[idx++] = v2; /* store current integer */
i += n; /* increment string index */
}
else {
n += n < norig ? 2 : 1; /* reset n if no match */
i = n; /* set string index to n */
idx = 0; /* reset array index to 0 */
}
}
}
if (idx && n < len) { /* if array has values, output */
printf ("integers :");
for (int j = 0; j < idx; j++)
printf (" %*d", n, a[j]);
putchar ('\n');
}
else
printf ("no solution found.\n");
return 0;
}
注意:并非所有角落案例都已经过评估,并且假定输入仅包含数字。 (如果您不希望的话,可以自由添加isdigit
的支票),应该进行进一步的测试,以满足自己任何奇数球案件的充分覆盖。
示例使用/输出
$ ./bin/intsepdecr
string : 9876543
integers : 9 8 7 6 5 4 3
$ ./bin/intsepdecr 109876543
string : 109876543
integers : 10 9 8 7 6 5 4 3
$ ./bin/intsepdecr 400399398397
string : 400399398397
integers : 400 399 398 397
$ ./bin/intsepdecr 400399398396
string : 400399398396
no solution found.
$ ./bin/intsepdecr 101176543
string : 101176543
no solution found.
仔细看看,如果您有任何其他问题,请告诉我。
答案 1 :(得分:0)
我可以给出一个如何解决这个问题的基本算法。
将字符串的第一个handle
数字转换为整数(最初为x
)。您甚至可以使用像x=1
这样的简单函数。 (我们说这个数字是N)
在strtoi
中找不到数字。将那么多位数转换为整数。
转换后的值是否等于N-1
。如果是,请继续并通过重复步骤2&amp;转换其余字符串。 3.(需要设置N-1
)
如果不等于N = N-1
,请从步骤1开始重复,仅此时间增加转换的位数。
如果您无法转换整个字符串并且N-1
大于字符串长度的一半,则退出程序并声明格式错误的字符串。
答案 2 :(得分:0)
这是我刚刚掀起的一些东西,我根据你的情况对它进行了测试,并且它可以正常工作
请注意,它是在c ++中,但转换为c会很简单。
string spaceNum(string in)
{
string numConvBuff;
size_t matchSize = 0;
if (in.size() == 1)
{
return to_string(in[0] - '0');
}
for (int i = 0; i < in.size() / 2; i++)
{
numConvBuff = in.substr(0, i + 1);
unsigned int numRes = stoul(numConvBuff) - 1;
string numResStr = to_string(numRes);
string n = in.substr(i + 1, numResStr.length());
if(numRes == stoul(n))
matchSize = i+1;
}
if (matchSize)
{
string out = in.substr(0, matchSize);
unsigned int numRes = stoul(out);
for (size_t i = matchSize; i < in.length();)
{
numRes--;
string numResStr = to_string(numRes);
string n = in.substr(i, numResStr.length());
out += " " + n;
i += numResStr.length();
}
return out;
}
return "";
}