我正在编写一个函数,该函数将返回给定数组中所有字符串的公共前缀的字符串。但是由于字符串的大小仍显示为零,所以我无法返回该字符串。
join
答案 0 :(得分:0)
正如我在评论中所提到的那样,字符串s
的大小始终为零,因为您实际上从未更改其大小。通过分配(=
,+=
)和resize
为两个,字符串的大小可以通过几种方式改变。您的程序当前具有未定义的行为,因为当您进行s[f]=A[i][f]
时,即使s
没有内容,您仍在索引f
上修改s
。
那么您如何解决呢?最初,您可以将s
的大小调整为m
的大小,并临时用空格填充。现在,您的if
语句中仍然存在逻辑问题。具体来说,对于else
,由于达到了else
,因此您需要删除所有剩余的内容并更改m
。有关完整的工作程序,请参见以下内容:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string longestCommonPrefix( const vector<string> &A ) {
string s;
int k = A.size();
int m = A[0].size();
for ( int i = 1; i < k; i++ ) {
int j = A[i].size();
if ( j < m ) m = j;
}
int f;
s.resize( m, ' ' ); // temporary, just to set the contents
for ( int i = 0; i < k - 1; i++ ) {
for ( f = 0; f < m; f++ ) {
if ( A[i][f] == A[i + 1][f] ) {
s[f] = A[i][f]; // copy the similar values
} else {
m = f; // if we reach a character which is not the same, then we reset m
s.resize( m ); // and resize the string
}
}
}
return s;
}
int main() {
vector<string> a;
a.push_back( "hello" );
a.push_back( "hell" );
a.push_back( "help" );
a.push_back( "he" );
cout << longestCommonPrefix( a );
getchar();
}
以上将显示he
的输出,这是所有三个单词的公共前缀。
以下是该功能的修改版本。首先,我将int
替换为size_t
,该尺寸应用于任何尺寸。其次,它引入了一些错误检查和简化。如果输入vector
的大小为0
,则不做任何检查并返回空字符串。如果大小为1
,则只需返回元素的内容。不需要工作。
此后,假设A[0]
是属于向量中所有元素的整个前缀。然后在for循环中查找不正确的时间,并相应地调整字符串的大小。您将注意到循环从1
开始,因为我们假设第一个元素是完整前缀。内部循环也小于s.size()
,因此s
缩小时,它就占了。
string longestCommonPrefix( const vector<string> &A ) {
size_t k = A.size();
if ( k == 0 )
return "";
if ( k == 1 )
return A[0];
string s = A[0];
for ( size_t i = 1; i < k - 1; i++ ) {
if ( A[i].size() < s.size() ) s.resize( A[i].size() );
for ( size_t f = 0; f < s.size(); f++ ) {
if ( A[i][f] != A[i + 1][f] ) {
s.resize( f );
}
}
}
return s;
}
编辑:第二个版本中存在一个问题,超出了范围。 UB又一次(哎呀)。我在第一个for
循环中添加了一个检查,如果它大于s
A[i]
的大小
答案 1 :(得分:0)
正如其他人所提到的,s[f]=A[i][f];
处有未定义的行为,并给出了实现,但是这是c ++ 14或更高版本的另一种版本,带有stl
算法,
#include<algorithm>
#include<string>
#include<numeric>
#include<vector>
std::string longest_common_prefix(const std::vector<std::string>& v) {
if (v.size() == 0) {
return "";
}
auto begin = std::begin(v[0]), end = std::end(v[0]);
end = std::accumulate(std::begin(v) + 1, std::end(v), end, [begin](auto end, const auto& s) {
return std::mismatch(begin, end, std::begin(s), std::end(s)).first;
});
return std::string(begin, end);
}