【问题标题】:C++ - string Input in a specific wayC++ - 以特定方式输入字符串
【发布时间】:2016-10-12 17:33:42
【问题描述】:

我想以特定方式从用户那里获取输入,例如以下方式:

L1 L2 L3 N 

L1,L2,L3 是由空格分隔的字符串。 N是一个整数。我尝试使用cin,但速度很慢。我需要快速获得输入。字符串 L2 也重复了 N 次。所以我必须存储l1 + l2*N + l3。我尝试了字符串,但它变得太慢了。我得了 TLE。

这是我存储它们的方式:

 #include<bits/stdc++.h>
using namespace std;
int main (){
 string l1,l2,l3;
  int n;
  cin>>l1>>l2>>l3>>n;
  string r;
 r.reserve(l1.size()+n * l2.size()+l3.size());
r += l1;
 for (int i=0; i<n;i++)
  r +=l2;

 r += l3;
 cout<<r<<endl;
return 0;
 }

And then iterated it in 2 separate for loops with maximum 1000 iterations in each loop.

我怎样才能有效地存储它们?我知道向量,但我不擅长它们。因此,如果有人知道如何将它们按此序列存储在向量中,请帮助我。或者如果它们可以存储在字符数组中,那么该怎么做呢?

【问题讨论】:

  • 你确定是输入让你慢了下来,而不是你的算法吗?
  • 我怀疑是cin 太慢了,这很可能是您当前读取字符串的方法。字符串是/是 L2*N 空格分隔的,还是/是/它们连接在一起(所以技术上只是一个长字符串)?你应该如何存储它们的答案完全取决于你想在以后使用这些字符串。
  • 是的,我想是的,因为我在其余代码中所做的只是迭代字符串,即(l1+l2*n+l3) 在 2 个单独的 for loop 中,这将在最坏的情况下运行 1000 次。
  • 如果您向我们展示一个输入格式的具体示例,以及您当前代码的相关部分以供阅读,怎么样?
  • for (int i=0; i&lt;n;i++) r +=l2; 会做很多工作。特别是如果您在一些嵌套的 for 循环中执行此操作多达 1,000,000 次。

标签: c++ arrays string vector character


【解决方案1】:

好的。因此,让我们首先将实际读取与其他代码隔离开来:

struct foo { 
    std::string l1, l2, l3; 
    int n;

    friend std::istream &operator>>(std::istream &is, foo &f) { 
       return is >> f.l1, >> f.l2 >> f.l3 >> n;
    }
};

这样我们就可以将一个包含这些记录的文件读入一个向量,如下所示:

std::vector<foo> data { std::istream_iterator<foo>(infile), {} };

我猜这(本身)不会成为瓶颈。如果确实需要,可能有更快的方法来完成这项工作,但我怀疑它是否真的需要。

根据需要如何进行搜索的 cmets,我们可以进行搜索,而无需将第二个字符串扩展到 n 出现的 l2

搜索是从字符串的开头到最后(最右边)某个其他字符出现的一个字符。

由于“结束”模式是单个字符,我们可以很容易地做到这一点,而无需扩展中间字符串 (L2)。逻辑基本上是:

if L3 contains end_pattern
   total = count(L1) + count(L2) * n + count(L3.substr(0, pattern_pos))
else if L2 contains end_pattern
    total = count(L1) + count(L2) * (n-1) + count(L2.substr(0, pattern_pos))
else if L1 contains end_pattern
    total = count(L1.substr(0, pattern_pos))
else
    total = 0; // pattern isn't present anywhere

至少如 cmets 中所述,似乎不需要 cmets 中描述的 O(N2) 算法。

【讨论】:

  • 感谢您的帮助。对于搜索部分,假设如果我有这个输入 aabba bbba aaaa 2 现在我想计算右侧第一个 b 之后的 a 数。可以不使用 l2 n 次的串联来完成吗?
  • @samthornton:“在右侧第一个 B 之后”是什么意思?
  • 我的意思是我想从右侧计算 a 的数量,但只有在遇到至少 1 b 之后才能计算,否则计数将为零。例如ba ab aa 4 是输入然后它变成ba abababab aa(忽略空格)现在我想从右侧计算a 的数量,即index = string.size() -1 但只有在我遇到一个 b 之后。那就是我会从右侧开始,在看到一个 b 之后,我会数 a 的数量。这里右侧第一个 b 之后的 a 数是 5
  • 我也开发了同样的方案。我意识到问它是多么愚蠢。感谢您的时间和精力。
猜你喜欢
  • 2018-04-04
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 2021-12-06
  • 2021-08-25
相关资源
最近更新 更多