Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;字数到整数_C++ - Fatal编程技术网

C++ C++;字数到整数

C++ C++;字数到整数,c++,C++,我正在开发一个程序,用文字而不是数字进行基本计算。例如,五加二将输出七 程序变得更加复杂,需要输入,例如二百零一+五千六 (201+5006) 通过运算符重载方法,我将每个数字拆分并分配给它自己的数组索引 两个是[0],一百个是[1],一个是[2]。然后阵列循环使用5006 我的问题是,要执行实际计算,我需要将数组中存储的字转换为实际整数 我有这样的常量字符串数组作为单词库: const string units[] = { "", "one", "two", "three", "four",

我正在开发一个程序,用文字而不是数字进行基本计算。例如,五加二将输出七

程序变得更加复杂,需要输入,例如二百零一+五千六 (201+5006)

通过运算符重载方法,我将每个数字拆分并分配给它自己的数组索引

两个是[0],一百个是[1],一个是[2]。然后阵列循环使用5006

我的问题是,要执行实际计算,我需要将数组中存储的字转换为实际整数

我有这样的常量字符串数组作为单词库:

const string units[] = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

const string teens[] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };

const string tens[] = { "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };

如果我的“令牌”数组在索引0、1和2中存储了221个,我不确定将它们转换为整数的最佳方法是什么。

我同意Jesse关于使用映射将值映射到数组的观点,从那以后,您可以执行以下操作:

mymap["two"] * mymap["hundred"] + mymap["one"] 
当然,对于像“伍佰贰仟伍佰柒”这样的案例,您必须小心,在这种情况下,您必须检查除青少年以外的特殊案例:

const string temp[] = {"five","hundred","two","thousand","fifty","seven"};

int handleThree(int start)  {
    if( mymap[temp[start+ 3]] > 100) //check for special case, in which case you handle 4 words instead of three
       return (myap[temp[start]] * mymap[temp[start+1]] + mymap[temp[start+2]]) * mymap[temp[start+3]];
    else
       return mymap[temp[start]] * mymap[temp[start+1]] + handleTwo(start+2)
}

int handleTwo(int start) {
    if(mymap[temp[start]] / 10 == 1) //check if it's a teen, return teen value
       return mymap[temp[start]]
    if(mymap[temp[start+1]] > 90) //check for another special case, "five thousand one hundred and fifty seven", for example should use this case
       return mymap[temp[start]] * mymap[temp[start+1]]
    else
       return mymap[temp[start]] + mymap[temp[start+1]];
}
当然,你还需要注意更多的案例(“五十六万二千零十三”)但这会偷走你的乐趣和学习经验来帮助你处理这些案例,但我相信这应该足以让你开始


<> P>也不是,我不是C++中最好的,所以我要为我的代码中的任何问题道歉,如果你应该找到它们,但是从我的测试中,我用我写的主循环来工作(如果需要的话,我会提供它,但是我认为你自己写这个会对你有好处)

< P>我的一个诀窍是向后而不是向前地解析令牌。并在您返回令牌时保持比例因子。对于每个标记,可以添加到当前值(按scalefactor的当前值缩放)或调整scalefactor,具体取决于遇到的标记

这是我的实现(有些位不包括在内,您需要添加一些逻辑来处理数百万)

#包括
#包括
#包括
整型标记到整型(常量std::vector&s)
{
int标度=1;
int-rv=0;
为了(
std::vector::const_reverse_迭代器it=s.rbegin();
它!=s.rend();
++它
)
{
std::string cw=*it;
//增加当前价值的东西
如果(cw=“一”){rv+=1*刻度;}
如果(cw=“2”){rv+=2*刻度;}
如果(cw=“三”){rv+=3*刻度;}
如果(cw=“四”){rv+=4*刻度;}
// ...
如果(cw=“九”){rv+=9*刻度;}
如果(cw=“十”){rv+=10*刻度;}
//青少年
如果(cw=“十一”){rv+=11*刻度;}
如果(cw=“十二”){rv+=12*刻度;}
// ...
如果(cw=“十九”){rv+=19*刻度;}
//10的倍数
如果(cw=“二十”){rv+=20*刻度;}
如果(cw=“三十”){rv+=30*刻度;}
如果(cw=“四十”){rv+=40*刻度;}
// ...
如果(cw=“90”){rv+=90*刻度;}
//影响以下条目比例的因素
如果(cw=“100”){scale*=100;}
if(cw=“千”){if(scale==100){scale=1000;}否则{scale*=1000;}
}
返回rv;
}
模板
结构为
{
as_vec&operator()(常量T&T)
{
v、 推回(t);
归还*这个;
}
std::vector build(){return v;}
std::向量v;
};
int main()
{
assert(421==tokens_to_int(as_vec()(“四”)(“百”)(“二十”)(“一”).build());
assert(422==tokens_to_int(as_vec()(“四”)(“百”)(“二十”)(“两”).build());
assert(11000==tokens_to_int(as_vec()(“十一”)(“千”).build());
断言(21201==tokens to int(as_vec()(“二十”)(“一”)(“千”)(“两”)(“百”)(“一”).build());
断言(100001==tokens_to_int(as_vec()(“一”)(“百”)(“千”)(“一”).build());
断言(101000==tokens_to_int(as_vec()(“一”)(“百”)(“一”)(“千”).build());
断言(411201==tokens-to-int(as-vec()(“四”)(“百”)(“十一”)(“千”)(“两”)(“百”)(“一”).build());
assert(999999==令牌到int(as_vec()(“九”)(“百”)(“九十”)(“九”)(“千”)(“九”)(“百”)(“九十”)(“九”).build());
}

如果您只想将单个数字字转换为整数,那么就很容易了。只需在for循环中扫描这些数组,直到找到匹配项。或者你也可以按照杰西的建议使用地图。解析像“三万二千三百四十二”这样的整数短语更为棘手。你想帮助解决哪一个问题?我试过很多if语句,但我发现最难的是青少年numbers@AdrianRatnapala我想我需要多个字号的帮助。你们可能会发现,看看欧拉计划第17个问题的答案很有用,这个问题涉及到这一点:,这看起来很好,比我尝试的要干净得多(一旦你接受了预先标记化的需要)。唯一需要关心的是检测像“一千零二一九”这样的废话。哦,伙计,非常感谢你,你为我节省了一些非常宝贵的工作时间!
#include <vector>
#include <string>

#include <assert.h>

int tokens_to_int( const std::vector<std::string> &s )
{
  int scale = 1;
  int rv=0;
  for(
      std::vector<std::string>::const_reverse_iterator it = s.rbegin();
      it!=s.rend();
      ++it
     )
  {
    std::string cw = *it;
    //Things that add to the current value
    if( cw == "one" )   { rv += 1 * scale; }
    if( cw == "two" )   { rv += 2 * scale; }
    if( cw == "three" ) { rv += 3 * scale; }
    if( cw == "four" )  { rv += 4 * scale; }
    // ...
    if( cw == "nine" )   { rv += 9 * scale; }
    if( cw == "ten" )    { rv += 10 * scale; }

    // Teens
    if( cw == "eleven" )  { rv += 11 * scale; }
    if( cw == "twelve" )  { rv += 12 * scale; }
    // ...
    if( cw == "nineteen" )  { rv += 19 * scale; }

    // Multiples of 10
    if( cw == "twenty" )    { rv += 20 * scale; }
    if( cw == "thirty" )    { rv += 30 * scale; }
    if( cw == "fourty" )    { rv += 40 * scale; }
    // ...
    if( cw == "ninety" )    { rv += 90 * scale; }

    //Things that effect scale for following entries
    if( cw == "hundred" ) { scale *= 100; }
    if( cw == "thousand" ) { if( scale==100) { scale=1000; } else { scale*=1000; } }
  }

  return rv;
}

template<typename T>
struct as_vec
{
  as_vec<T>& operator()(const T & t )
  {
    v.push_back(t);
    return *this;
  }

  std::vector<T> build() { return v; }

  std::vector<T> v;
};

int main()
{
  assert(421 == tokens_to_int( as_vec<std::string>()("four")("hundred")("twenty")("one").build() ) );
  assert(422 == tokens_to_int( as_vec<std::string>()("four")("hundred")("twenty")("two").build() ) );
  assert(11000 == tokens_to_int( as_vec<std::string>()("eleven")("thousand").build() ) );
  assert(21201 == tokens_to_int( as_vec<std::string>()("twenty")("one")("thousand")("two")("hundred")("one").build() ) );
  assert(100001 == tokens_to_int( as_vec<std::string>()("one")("hundred")("thousand")("one").build() ) );
  assert(101000 == tokens_to_int( as_vec<std::string>()("one")("hundred")("one")("thousand").build() ) );
  assert(411201 == tokens_to_int( as_vec<std::string>()("four")("hundred")("eleven")("thousand")("two")("hundred")("one").build() ) );
  assert(999999 == tokens_to_int( as_vec<std::string>()("nine")("hundred")("ninety")("nine")("thousand")("nine")("hundred")("ninety")("nine").build() ) );
}