【问题标题】:c++ toupper() to compare two stringsc++ toupper() 比较两个字符串
【发布时间】:2014-03-28 19:59:46
【问题描述】:

我创建了一组算法,它接受字符串向量的输入,检查是否有任何字符串出现多次:如果是,则从向量中删除所有额外出现的字符串,然后输出新的,'lighter ' 没有冗余的数组。

它很好用,但现在我要让它不区分大小写;我试图简单地将toupper() std 函数添加到== 比较语句,但它似乎不起作用。

我对 Java 有更熟悉的背景,并且正在努力学习 C++。
有人可以告诉我如何更正我的语法吗?

// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;

// Check uniqueness.
for (int i = 0; i < count; i++)
    for (int j = i+1; j < count; j++) {
        if (toupper(list[i]) == toupper(list[j])) {
            list[j] = "";
            count--;
        }
    }

// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;

【问题讨论】:

  • 为什么不将std::vector&lt;std::string&gt;std::remove_iflambda 一起使用?
  • @OMGtechy 不区分大小写吗?
  • @Jim22150 列表中字符串的顺序需要维护吗?
  • @Mahesh,是的,输出相同的顺序,我想保持我的算法相同。这不是问题的意义所在(对 OMGtechy 和 Scott)。
  • 怎么不工作了?什么是清单? std::string[N]?

标签: c++ string toupper


【解决方案1】:

您的循环在list array 向量中留下 "holes",但 array 向量的大小不会改变(但你减少你的上限count)

可能还有很多其他选择,但如果您不想对其进行太多修改,可能需要在一个额外的循环中从 list 复制 非空 元素数组变成一个新数组

编辑:整合一些答案

首先我们将有一个函数来执行 toUpper(这是从 @Jim22150 修改的)

std::string stringToUpper(const std::string &input) {
    std::string toBeModified=input;
    std::transform(toBeModified.begin(), toBeModified.end(), toBeModified.begin(), ::toupper);
    return toBeModified;
}

现在,我们不能留下漏洞,所以我们应该使用擦除(正如@Scott Christopher Stauffe 指出的那样):

// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;

// Check uniqueness.
for (int i = 0; i < count; i++)
    for (int j = i + 1; j < count; j++) {
        if(stringToUpper(list[i]) == stringToUpper(list[j])) {
            list.erase(j,1);
            count--;
        }
    }
}

// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << newlist[i];
}
cout << endl << endl;

【讨论】:

  • 是的,最好避免这种情况。我正在尝试实施 Scott 的建议,但看起来我可能需要另一个 for 循环,如果可能的话我想避免。
  • @Jim22150 ... 是的,但真正的问题是你不能缩小数组,除非你复制它。如果您可以在数组上使用矢量而不是,那将允许您从中删除...
  • list[] 一个向量,而不是一个数组。
  • @Jim22150 好的...这很令人困惑。我在上面编辑了我的答案,以整合一些漂浮的想法。我真的没试过。
【解决方案2】:

@DaveS,谢谢戴夫,我会试试的;它看起来干净而简短。但是,我发现使用变换并复制旧向量的方法更脏。

    // Output old list.
    cout << endl << "==========\nOld list:\n==========";
    for (int i = 0; i < count; i++) {
        cout << endl << list[i];
    }
    cout << endl << endl;

    // Check uniqueness.
    for (int i = 0; i < count; i++)
        for (int j = i + 1; j < count; j++) {
            std::transform(list[i].begin(), list[i].end(), list[i].begin(), ::toupper);
            std::transform(list[j].begin(), list[j].end(), list[j].begin(), ::toupper);
            if (list[i] == list[j]) {
                newlist[j] = "";
                count--;
            }
        }

    // Output new list.
    cout << endl << "==========\nNew list:\n==========";
    for (int i = 0; i < count; i++) {
        cout << endl << newlist[i];
    }
    cout << endl << endl;

【讨论】:

    【解决方案3】:

    如果您想像处理 Java 字符串一样轻松地处理 C++ 字符串,那么Boost String Algorithms Library 是您的最佳选择。对于新手 C++ 程序员来说,安装 Boost 可能有点困难(尽管与许多其他 C++ 库相比,它轻而易举),但它是有回报的。

    您的问题基本上会简化为:

    boost::algorithm::to_upper_copy(list[i]) == boost::algorithm::to_upper_copy(list[j])
    

    【讨论】:

      【解决方案4】:

      我只是对 toupper 做了一个快速的谷歌搜索,但没有找到它的任何字符串版本。我见过的唯一标准 touppper() 是int toupper(int c); - 这意味着您只能使用它来比较单个字符!你试过stricmp()吗?

              if ( 0 == _stricmp(list[i], list[j]) ) {
                  list[j] = "";
                  count--;
              }
      

      根据您的编译器,您可能有也可能没有此功能供您使用。

      【讨论】:

      • 我使用的是 VS'13,所以这个功能是理想的,但它似乎只用于单个字符,而不是整个字符串。所以我可以使用它,但我必须在条件内部创建另一个 for 循环,对吗?
      • @Jim22150, stricmp() 将接受两个字符串作为参数,因此不需要另一个循环。如果您想继续使用toupper(),那么您需要一个循环来比较各个字符。
      【解决方案5】:

      首先,

      list[j] = ""; // should never work. 
      

      您可以使用擦除删除字符。

      list.erase(j, 1);
      

      或者,为了完全避免这种情况,您可以使用临时的“builder”字符串,并在需要时将其 push_back 字符。

      【讨论】:

      • .erase() 似乎仅适用于向量中的字符,但是我需要擦除向量的字符串元素。任何线索,最好没有额外的循环?
      • 有人提到它是一个数组,而不是一个向量
      • @jsantander 是的,抱歉,我调整了我的问题;向量,而不是数组。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-04
      • 2015-11-13
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多