如何在 C++ 中检查字符串的特定条件

how to check a string for specific conditions in C++

以下代码片段显示了我当前输出的一小部分:

1464:       ebfffe4d        bl      da0 <memcpy@plt>
14bc:       ebfffe37        bl      da0 <memcpy@plt>

输出中的每一行都引用一个字符串。我想要实现的是,在这个 只有 memcpy@plt 才会打印一次。当字符串包含“bl”时,则名称 <...> 内应该打印并且只打印一次,因为 <...> 内的名称是相同的 在这两种情况下。有没有办法得到这个? 我当前的代码如下所示:

class CallFunction {
    private:
        vector<string> content;
    public:
        CallFunction(vector<string> content) {
            this->content = content;
        }
        void print() {
            for(string line: content) {
                if(line.find("bl") != std::string::npos
                && line.find("<") != std::string::npos) {
                    cout << line << endl;
                }
            }
        }
};

int main() {
    string fileName = "libndkmod.s";
    vector<string> content = readFile(fileName);
    CallFunction cf = CallFunction(content);
    cf.print();
}

在此先致谢并致以亲切的问候!

我们可以使用unordered_set去重子串,如果相同的子串已经被打印过,则跳过它。

这一步可以抽成一个方法跟在single responsibility principle之后,比在print函数中处理重复更自然,这个工作就交给你了。

我们使用 unordered_set 而不是 std::set 因为 unordered_set 会更快搜索。

我已经将 for 循环从 for(string line: content) 更改为 for(const string& line: content),然后我们避免了原始字符串的副本,以提高性能。基本上,我们更愿意对除原始类型之外的对象使用 for(const auto& item:...) 以避免复制。

我们存储了c++17引入的string_view来避免复制子字符串,它会节省内存,因为我们避免了不必要的复制。


#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>
using namespace std;

class CallFunction {
 private:
  vector<string> content;

 public:
  CallFunction(vector<string> content) { this->content = content; }
  void print() {
    std::unordered_set<std::string_view> mem;
    for (const string& line : content) {
      auto left_pos = line.find("bl");
      auto right_pos = line.find(">");
      if (left_pos != std::string::npos && right_pos != std::string::npos) {
        std::string_view sub_view = {&line.front() + left_pos,
                                     right_pos - left_pos + 1};
        if (mem.count(sub_view)) continue;
        mem.insert(sub_view);
        cout << line << endl;
      }
    }
  }
};

int main() {
  string fileName = "libndkmod.s";
  vector<string> content = {
      "1464:       ebfffe4d        bl      da0 <memcpy@plt>",
      "14bc:       ebfffe37        bl      da0 <memcpy@plt>",
      "14bc:       ebfffe37        bl      da0 <memcmp@plt>"};
  CallFunction cf = CallFunction(content);
  cf.print();
}

Online demo