函数返回零大小的字符串,即使其大小不为零

时间:2020-01-18 17:29:41

标签: c++

我正在编写一个函数,该函数将返回给定数组中所有字符串的公共前缀的字符串。但是由于字符串的大小仍显示为零,所以我无法返回该字符串。

join

2 个答案:

答案 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);
}

相关问题