字符串到空格分隔的整数

时间:2017-05-16 04:39:43

标签: c string integer

我有一个包含整数的字符串(按降序),然后输出应该是空格分隔的整数。整数不是负数。

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()

如何达到预期效果?

3 个答案:

答案 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)

我可以给出一个如何解决这个问题的基本算法。

  1. 将字符串的第一个handle数字转换为整数(最初为x)。您甚至可以使用像x=1这样的简单函数。 (我们说这个数字是N)

  2. strtoi中找不到数字。将那么多位数转换为整数。

  3. 转换后的值是否等于N-1。如果是,请继续并通过重复步骤2&amp;转换其余字符串。 3.(需要设置N-1

  4. 如果不等于N = N-1,请从步骤1开始重复,仅此时间增加转换的位数。

  5. 如果您无法转换整个字符串并且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 "";
}