需要有关改进我的代码的建议:搜索算法

时间:2013-04-08 15:53:05

标签: c++ search divide

我对C ++很陌生,需要一些建议。 在这里,我编写了一个代码,用于测量数组中出现任意整数x的次数,并输出比较结果。

但是我已经通过使用多向分支(“Divide and conqurer!”)技术读到了这一点,我可以让算法运行得更快。

有人能指出我正确的方向我该怎么做呢?

这是我使用的其他方法的工作代码:

#include <iostream>
#include <cstdlib>
#include <vector>

using namespace std;

vector <int> integers;
int function(int vectorsize, int count);
int x;
double input;

int main()
{
cout<<"Enter 20 integers"<<endl;
cout<<"Type 0.5 to end"<<endl;

while(true)
{
cin>>input;

if (input == 0.5)
break;

integers.push_back(input);
}

cout<<"Enter the integer x"<<endl;
cin>>x;

function((integers.size()-1),0);

system("pause");

}

int function(int vectorsize, int count)
{
    if(vectorsize<0) //termination condition
{
    cout<<"The number of times"<< x <<"appears is "<<count<<endl;
    return 0;
}    

if (integers[vectorsize] > x)
{
    cout<< integers[vectorsize] << " > " << x <<endl;
}

if (integers[vectorsize] < x)
{
    cout<< integers[vectorsize] << " < " << x <<endl;
}
if (integers[vectorsize] == x)
{
    cout<< integers[vectorsize] << " = " << x <<endl;

    count = count+1;
}

return (function(vectorsize-1,count));
}

谢谢!

3 个答案:

答案 0 :(得分:4)

如果数组未排序,只需使用单个循环将每个元素与x进行比较。除非你忘了告诉我们什么,否则我认为不需要任何更复杂的东西。

如果对数组进行排序,则存在具有更好的渐近复杂度的算法(例如,二分搜索)。但是,对于20个元素的数组,简单的线性搜索应该仍然是首选策略。

答案 1 :(得分:2)

如果你的数组是一个排序的数组,你可以使用除法来征服策略:

Efficient way to count occurrences of a key in a sorted array

答案 2 :(得分:1)

分而治之算法只有在您可以使用它消除一些工作,或者如果您可以在多个计算单元中并行化分割的工作部分时才有用。在您的情况下,第一个选项可以使用已经排序的数据集,其他答案可能已经解决了问题。

对于第二种解决方案,算法名称为map reduce,它将数据集拆分为多个子集,将子集分配给尽可能多的线程或进程,并收集结果以“编译”它们(该术语实际上是“减少” )在一个有意义的结果。在您的设置中,这意味着每个线程将扫描其自己的数组切片以计算项目,并将其结果返回到“reduce”线程,这将添加它们以返回最终结果。 此解决方案仅适用于大型数据集。

在SO上有关于mapreduce和c ++的问题,但我会尝试在这里给你一个示例实现:

#include <utility>
#include <thread>
#include <boost/barrier>

constexpr int MAP_COUNT = 4;

int mresults[MAP_COUNT];

boost::barrier endmap(MAP_COUNT + 1);

void mfunction(int start, int end, int rank ){
    int count = 0;
    for (int i= start; i < end; i++)
        if ( integers[i] == x) count++;
    mresult[rank] = count;
    endmap.wait();
}

int rfunction(){
    int count = 0;
    for (int i : mresults) {
        count += i;
    }
    return count;
}

int mapreduce(){
    vector<thread &> mthreads;
    int range = integers.size() / MAP_COUNT;
    for (int i = 0; i < MAP_COUNT; i++ )
        mthreads.push_back(thread(bind(mfunction, i * range, (i+1) * range, i)));
    endmap.wait();
    return rfunction();
}

填充integers向量后,调用上面定义的mapreduce函数,该函数应返回预期结果。如您所见,实现非常专业:

  • map和reduce函数是特定于您的问题的,
  • 用于map的线程数是静态的,
  • 我遵循了你的风格并使用了全局变量,
  • 为方便起见,我使用boost::barrier进行同步

但是,这应该让您了解算法,以及如何将其应用于类似的问题。

警告:代码未经测试