0

首先,我必须说我正在迈出 C++ 的第一步,而且我来自 PHP,所以请原谅这个基本问题。我一直在寻找和测试许多替代方案,但我似乎无法理解如何在 PHP 中执行此操作,distance($str1, $str2)以便读取函数distance返回的任何内容。

我想要做的是调用一个模板,它应该返回两个字符串之间的 Levenshtein 距离。

这是我的代码

template <class T> unsigned int edit_distance(const T& s1, const T& s2)
{
    const size_t len1 = s1.size(), len2 = s2.size();
    vector<vector<unsigned int> > d(len1 + 1, vector<unsigned int>(len2 + 1));

    d[0][0] = 0;
    for(unsigned int i = 1; i <= len1; ++i) d[i][0] = i;
    for(unsigned int i = 1; i <= len2; ++i) d[0][i] = i;

    for(unsigned int i = 1; i <= len1; ++i)
        for(unsigned int j = 1; j <= len2; ++j)

            d[i][j] = std::min( std::min(d[i - 1][j] + 1,d[i][j - 1] + 1),
                               d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1) );
    return d[len1][len2];
}

string text1="house";
string text2="houses";
edit_distance <int> (text1, text2);

问题在线edit_distance <int> (text1, text2);,Xcode给出的错误是:C++ requires a type specifier for all declarations

同样,我知道这一定是非常基本的,但我找不到正确的方法。任何正确方向的提示将不胜感激。

谢谢!

4

2 回答 2

1

为了测试我的怀疑,我拿了你的代码,添加了最小的包含和使用声明,以允许编译器调用edit_distance并编译它。这是我编译的文件的完整内容:

#include <vector>
#include <string>
#include <algorithm>
using std::vector;
using std::string;

template <class T> unsigned int edit_distance(const T& s1, const T& s2)
{
    const size_t len1 = s1.size(), len2 = s2.size();
    vector<vector<unsigned int> > d(len1 + 1, vector<unsigned int>(len2 + 1));

    d[0][0] = 0;
    for(unsigned int i = 1; i <= len1; ++i) d[i][0] = i;
    for(unsigned int i = 1; i <= len2; ++i) d[0][i] = i;

    for(unsigned int i = 1; i <= len1; ++i)
        for(unsigned int j = 1; j <= len2; ++j)

            d[i][j] = std::min( std::min(d[i - 1][j] + 1,d[i][j - 1] + 1),
                               d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0 : 1) );
    return d[len1][len2];
}

string text1="house";
string text2="houses";
edit_distance <int> (text1, text2);

我的怀疑得到了证实;我收到以下错误:

main.cpp:26:22: error: C++ requires a type specifier for all declarations
edit_distance <int> (text1, text2);
                     ^~~~~

这是您提到的确切错误,因此我相信您很可能犯了与我在测试源代码中包含的相同的错误。大多数有经验的程序员只会假设您的不完整代码是为了简洁而显示的,并且会自动插入一些可以完全避免此错误的周围代码。


你不明白的事情似乎是在 C++ 代码中不只是去任何地方。C++ 程序不仅仅是解释器在源代码中读取它们时执行的一系列语句。

C++ 是一种编译语言。程序是函数、类等的一系列声明和定义。语句,即执行工作的代码,只在定义内部。您的函数调用edit_distance<int>(text1, text2);不在任何定义中,因此编译器不期待声明并且不知道您在说什么。所以把它放在一个定义里。您可能想要使用函数定义:

void foo() {
    string text1="house";
    string text2="houses";
    edit_distance <int> (text1, text2);
}

此外,当编译的代码被执行时,执行开始于一个特殊的入口点函数,main。只有可通过此入口点访问的代码才会被执行。(实际上这不是真的,但其他情况目前无关紧要。)

因此,您需要一个最终导致您要执行的代码的 main 函数。你可以main调用上面的foo,或者你可以直接把你的代码放在main

int main() {
    string text1="house";
    string text2="houses";
    edit_distance <int> (text1, text2);
}

此代码仍然无法编译,因为该<int>部分不正确。尖括号内的类型成为T在 edit_distance 函数模板中分配的类型:

template <class T> unsigned int edit_distance(const T& s1, const T& s2)

edit_distance<int>说设置 T 等于 int:

unsigned int edit_distance(const int& s1, const int& s2)

这不是你想要的。您可能希望将 T 设置为等于字符串,以便 s1 和 s2 参数是字符串。

int main() {
    string text1="house";
    string text2="houses";
    edit_distance<string>(text1,text2);
}

接下来,您可能希望实际查看返回值。#include <iostream>在源代码的开头添加其他包含,然后使用 main 函数:

int main() {
    string text1="house";
    string text2="houses";
    std::cout << edit_distance<string>(text1,text2) << '\n';
}

完整、可编译的程序

于 2012-09-29T19:45:15.230 回答
1

template <class T> unsigned int edit_distance(const T& s1, const T& s2)

类型 T 可以直接从参数中推断出来。所以根本不需要指定类型。打电话

edit_distance(text1, text2);

从函数内部。您可以对模板支持的任何类型执行此操作。如果不支持该类型,您将收到编译时错误。

仅当无法推断类型时才需要显式指定类型。在您的情况下,您指定的类型<int>与您提供的参数不匹配。

于 2012-09-29T21:02:06.950 回答