【问题标题】:Does C++ have a sequential search function?C++ 有顺序搜索功能吗?
【发布时间】:2009-03-26 14:53:06
【问题描述】:

我有一个小的未排序数组,我想找到特定值的 索引。 C++ 是否为此内置了顺序搜索功能,还是每次出现循环时您都自己编写循环?

我专门使用 C 风格的数组,例如:

std::string arr[5] = { "EVEN", "ODD", "NONE", "MARK", "SPACE" };

我需要用户提供的值的索引。

【问题讨论】:

  • 你指的是哪个数组?类型[大小]?
  • std::string array[5] 是我需要使用它的大约六个典型示例中的一个。
  • 我明白了。这正是我的意思。请您编辑问题以澄清您的意思是 C 风格的数组,而不仅仅是 STL 容器?

标签: c++ search


【解决方案1】:

使用来自 STL-算法-库的 std::find(),或特定容器的 find()-方法。

【讨论】:

  • 谢谢。我觉得问起来很傻,但是我可以比通过搜索“C++ 顺序搜索”更快地编写函数。
  • 顺便说一句,您可以在容器上使用 std::find 而不仅仅是 STL 容器。例如,可以使用 std::find() 搜索简单的 C 样式数组
  • @sharptooth:所有 STL 迭代器的设计都使其具有与指针相同的语义。因此指针是一个迭代器,用于 STL 目的:)
  • @sharptooth: std::find(the_array, the_array + num_elements, the_value)
  • @sharptooth:链接页面有一个很好的例子,使用了一个数组和一个向量。
【解决方案2】:

std::find() 应该可以工作:

#include <stdio.h>
#include <algorithm>
#include <string>

using std::string;

std::string arr[5] = { "EVEN", "ODD", "NONE", "MARK", "SPACE" };


int main() {

    string* pArrEnd = arr + sizeof( arr)/sizeof(arr[0]);

    string* pFound = std::find( arr, pArrEnd, "MARK");

    if (pFound == pArrEnd) {
        printf( "not found\n");
    }
    else {
        printf( "%s was found at index %d\n", pFound->c_str(), pFound - arr);
        printf( "or using STL: %d\n", std::distance( arr, pFound));
    }

    return 0;
}

【讨论】:

  • 使用 C++11,您可以使用来自 &lt;iterator&gt;auto pArrEnd = std::end(arr);。好看多了! ;-)
【解决方案3】:

您可以在容器上使用 STL 算法,而不仅仅是 STL 容器。例如,您可以在 C 样式数组中使用 std::find():

// alloc the array
static const size_t numItems = 100000;
int * items = new int[numItems];

// fill the array
for( size_t n = 0; n < numItems; ++n )
    items[n] = n;

// find 42 using std::find()
int* found = std::find(&items[0], &items[numItems], 42);
if( found == &items[numItems] )
{
    // this is one past the end, so 42 was not found
    items[0] = 42;
}
else
{
    // we found the first instance of 42 at this location
    // change it to 43
    *found = 43;
}

【讨论】:

  • 难道你不能只使用数组的名称而不是&amp;array[0]吗?
  • 当然。我只是更喜欢 &array[0] 因为它在语义上对我来说似乎更清楚一点。只是一种风格。
  • @warren:语义上 &array[0] 是第一个元素的地址,而 array 只是隐式转换为同一指针的数组。 John 只是在代码中明确说明编译器会在您的情况下隐式生成的内容。
  • 请注意 &items[numItems] 是未定义的行为(尽管它在大多数情况下会起作用,因为 &*(int*)0 在大多数情况下也会起作用)。我更喜欢 items + numItems ,这是有效的。 (由于对称原因,另一边的 items + 0 确实:))
  • @litb:我认为只有当您尝试取消引用指针时,它才是未定义的行为。
【解决方案4】:

我想你需要的是索引而不是迭代器。

int main()
{
    // for c++ vector
    typedef int Element;
    typedef std::vector<Element> CppVector;

    CppVector v;
    v.push_back( 2 );
    v.push_back( 4 );
    v.push_back( 8 );
    v.push_back( 6 );

    const Element el = 4;

    CppVector::const_iterator it = std::find( v.begin(), v.end(), el );
    if ( it == v.end() )
    {
        std::cout << "there is no such element" << std::endl;
    }
    else
    {
        const CppVector::size_type index = it - v.begin();
        std::cout << "index = " << index << std::endl;
    }

    // for C array
    typedef Element CVector[4];
    CVector cv;
    cv[0] = 2;
    cv[1] = 4;
    cv[2] = 8;
    cv[3] = 6;

    const std::size_t cvSize = sizeof( cv ) / sizeof( Element );

    std::cout << "c vector size = " << cvSize << std::endl;

    const Element* cit = std::find( cv, cv + cvSize, el );
    const std::size_t index = cit - cv;

    if ( index >= cvSize )
        std::cout << "there is no such element" << std::endl;
    else
        std::cout << "index = " << index << std::endl;
}

【讨论】:

  • 最好将两个指针的差异存储在 ptrdiff_t 类型中,它可以是负数(不是你的情况,但一般来说)。
  • 然后与 => cvSize 比较会发出警告。
【解决方案5】:

除了已经提到的 STL 可能性 (std::find) 之外,还有 POSIX 函数 lsearch(具有 c 语义)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    相关资源
    最近更新 更多