-5

私は次の出力を試しているアルゴリズムに取り組んでいます:

指定された値/入力:

char *Var = "1-5,10,12,15-16,25-35,67,69,99-105"; int size = 29;

ここで、 「1-5」は範囲値を示します。つまり、「1,2,3,4,5」と理解されますが、「,」のみの値は個々の値です。

私は最終出力が次のように完全な範囲の出力を与えるようなアルゴリズムを書いていました:

int list[]=1,2,3,4,5,10,12,15,16,25,26,27,28,29,30,31,32,33,34,35,67,69,99,100,101,102,103,104,105;

誰かがこの問題に精通している場合は、助けていただければ幸いです。前もって感謝します!

私の最初のコードアプローチは次のとおりです。

if(NULL != strchr((char *)grp_range, '-'))
{
    int_u8 delims[] = "-";
    result = (int_u8 *)strtok((char *)grp_range, (char *)delims);

    if(NULL != result)
    {
        start_index = strtol((char*)result, (char **)&end_ptr, 10);
        result = (int_u8 *)strtok(NULL, (char *)delims);
    }

    while(NULL != result)
    {
        end_index = strtol((char*)result, (char**)&end_ptr, 10);
        result = (int_u8 *)strtok(NULL, (char *)delims);
    }

    while(start_index <= end_index)
    {
        grp_list[i++] = start_index;
        start_index++;
    }
}

else if(NULL != strchr((char *)grp_range, ','))
{
    int_u8 delims[] = ",";
    result = (unison_u8 *)strtok((char *)grp_range, (char *)delims);

    while(result != NULL)
    {
        grp_list[i++] = strtol((char*)result, (char**)&end_ptr, 10);
        result = (int_u8 *)strtok(NULL, (char *)delims);
    }
}

ただし、「0-5」または「0,10,15」のいずれかがある場合にのみ機能します。汎用性が上がるのが楽しみです。

4

7 に答える 7

3

これは私のブーストアプローチです:

これはintの配列ではなく、intのベクトルを提供します

使用されるアルゴリズム: (何も新しいものはありません)

  • を使用して文字列を分割する,

  • を使用して個々の文字列を分割します-

  • low範囲を作り、high

  • この範囲を使用してベクトルにプッシュします

コード:-

#include<iostream>
#include<vector>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>


int main(){

    std::string line("1-5,10,12,15-16,25-35,67,69,99-105");
    std::vector<std::string> strs,r;
    std::vector<int> v;
    int low,high,i;
    boost::split(strs,line,boost::is_any_of(","));

for (auto it:strs)
{
    boost::split(r,it,boost::is_any_of("-"));

    auto x = r.begin();
    low = high =boost::lexical_cast<int>(r[0]);
    x++;
    if(x!=r.end())
        high = boost::lexical_cast<int>(r[1]);
    for(i=low;i<=high;++i)
      v.push_back(i);
}

for(auto x:v)
  std::cout<<x<<" ";

    return 0;

}
于 2013-09-12T13:05:07.240 に答える
2

問題は strtok の仕組みを誤解しているようです。これを見てください。

#include <string.h>
#include <stdio.h>

int main()
{
        int i, j;
        char delims[] = " ,";
        char str[] = "1-5,6,7";
        char *tok;
        char tmp[256];
        int rstart, rend;

        tok = strtok(str, delims);

        while(tok != NULL) {
                for(i = 0; i < strlen(tok); ++i) {
                        //// range
                        if(i != 0 && tok[i] == '-') {
                                strncpy(tmp, tok, i); 
                                rstart = atoi(tmp);
                                strcpy(tmp, tok + i + 1); 
                                rend = atoi(tmp);
                                for(j = rstart; j <= rend; ++j)
                                        printf("%d\n", j); 
                                i = strlen(tok) + 1;
                        }   
                        else if(strchr(tok, '-') == NULL)
                                printf("%s\n", tok);
                }   

                tok = strtok(NULL, delims);
        }   

        return 0;
}
于 2013-09-12T12:34:52.177 に答える
2

検索しないでください。一度に 1 文字ずつテキストを読み進めてください。数字が表示されている限り、それらを値に累積します。数字の後に a が続く場合は-、範囲を見ていることになり、次の数字セットを解析して範囲の上限を取得し、すべての値をリストに入れる必要があります。値の後に a が続かない場合、値は-1 つです。それをあなたのリストに入れてください。

于 2013-09-12T12:27:21.273 に答える
0

最初に文字列全体を数値と範囲に分割し (「,」デリミタを指定して strtok() を使用)、文字列を配列に保存してから、配列を検索して「-」を探します。存在する場合は、sscanf() を「%d-%」で使用しますそれ以外の場合は、単一の「%d」形式で sscanf を使用します。

関数の使用法は簡単にグーグルで検索できます。

于 2013-09-12T12:32:54.930 に答える
0

1 つのアプローチ:

「、」、「-」、数字の 3 種類のトークンを識別するパーサーが必要です。これにより、抽象化のレベルが上がり、文字より上のレベルで操作できるようになります。

次に、トークン ストリームを解析して、範囲と定数のリストを作成できます。

次に、そのリストを解析して、範囲を定数に変換できます。

仕事の一部を行ういくつかのコード:

#include <stdio.h>

// Prints a comma after the last digit. You will need to fix that up.
void print(int a, int b) {
  for (int i = a; i <= b; ++i) {
    printf("%d, ", i);
  }
}

int main() {
  enum { DASH, COMMA, NUMBER };
  struct token {
    int type;
    int value;
  };

  // Sample input stream. Notice the sentinel comma at the end.
  // 1-5,10,
  struct token tokStream[] = {
    { NUMBER, 1 },
    { DASH, 0 },
    { NUMBER, 5 },
    { COMMA, 0 },
    { NUMBER, 10 },
    { COMMA, 0 } };

  // This parser assumes well formed input. You have to add all the error
  // checking yourself.
  size_t i = 0;
  while (i < sizeof(tokStream)/sizeof(struct token)) {
    if (tokStream[i+1].type == COMMA) {
      print(tokStream[i].value, tokStream[i].value);
      i += 2;  // skip to next number
    }
    else { // DASH
      print(tokStream[i].value, tokStream[i+2].value);
      i += 4;  // skip to next number
    }
  }

  return 0;
}
于 2013-09-12T12:28:17.477 に答える