同一个函数调用不同的输入(数组),如何缩小我的语句?

时间:2021-07-08 23:57:09

I am tring to use insertion sort to sort 7 different size arrays.

我正在使用插入排序来排序7个不同大小的数组。

In main(), I know it looks silly to repeat calling the same function, but I really can't think of a way to simplify my code.

在main()中,我知道重复调用同一个函数看起来很傻,但是我真的想不出一种简化代码的方法。

Besides, I have utilized the switch cases to generate different size arrays. Is this a wise way to do taht?

此外,我还利用开关案例来生成不同大小的数组。这是一个明智的做法吗?

Hope anyone can help me.

希望有人能帮助我。

I have posted my code here.:

我已经把我的代码写在这里了。

#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>
using namespace std;

vector<int> n = { 100, 500, 1000, 2000, 5000, 8000, 10000 }; //Different input size
const int N = 20000; //random scale
int n0[100], n1[500], n2[1000], n3[2000], n4[5000], n5[8000], n6[10000]; //initialize input arrays
int *myArray[] = { n0, n1, n2 };



bool isAlreadyAdded(int value, int index, int *pointer)
{
    for (int i = 0; i < index; i++)
    {
        if (*pointer == value)
            return true;
        pointer++;
    }
    return false;
}

void generator(int size){

    int input_size = n[size];
    int *p, *p2; //create a pointer point to the arrays which we want to manipulate.

    switch (input_size)
    {
    case 100:
        p = n0;
        p2 = n0;
        //cout << "p = n0 :" << *p << endl;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
        break;

    case 500:
        p = n1;
        p2 = n1;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
        break;
    case 1000:
        p = n2;
        p2 = n2;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
        break;
    case 2000:
        p = n3;
        p2 = n3;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
        break;
    case 5000:
        p = n4;
        p2 = n4;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
        break;
    case 8000:
        p = n5;
        p2 = n5;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
        break;
    case 10000:
        p = n6;
        p2 = n6;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
        break;

    default:
        cout << "Invalid input_size" << endl;
    } //end swith cases.
}

void insertion_sort(int arr[], int length){
    int j, temp;

    for (int i = 0; i < length; i++){
        j = i;

        while (j > 0 && arr[j] < arr[j - 1]){
            temp = arr[j];
            arr[j] = arr[j - 1];
            arr[j - 1] = temp;
            j--;
        }
    }
}

void writeToFile(int array[], string fileName, int length)
{
    ofstream myfile;
    myfile.open(fileName);
    for (int i = 0; i < length; ++i)
    {
        myfile << array[i] << endl;
    }
    myfile.close();
}



int main() {

    for (int i = 0; i < n.size(); ++i){
        generator(i); // Parameter is the input size
    }


    insertion_sort(n0, sizeof(n0) / sizeof(n0[0]));
    insertion_sort(n1, sizeof(n1) / sizeof(n1[0]));
    insertion_sort(n2, sizeof(n2) / sizeof(n2[0]));
    insertion_sort(n3, sizeof(n3) / sizeof(n3[0]));
    insertion_sort(n4, sizeof(n4) / sizeof(n4[0]));
    insertion_sort(n5, sizeof(n5) / sizeof(n5[0]));
    insertion_sort(n6, sizeof(n6) / sizeof(n6[0]));

    //writeToFile(n0, "n0", sizeof(n0) / sizeof(n0[0]));


    cin.ignore();
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

4 个解决方案

#1


-1  

These are cases for compiler macros. You really don't want to end up having to update code in 100023965-zigtillion kind of places :-)

这些是编译器宏的情况。你真的不想在100023965-zigtillion的地方更新代码:-)

U can define a macro somewhat like this at the top of your file:

可以在文件的顶部定义一个类似于此的宏:

#define MYCODE(PARAM) p = PARAM; \
p2 = PARAM; \
for (int x = 0; x != input_size; ++x) { \
  int tmp = 1 + (rand() % N); //Shift right by 1. \
  while (x != 0 && isAlreadyAdded(tmp, x, p2)) \
    tmp = 1 + (rand() % N); \
  *p = tmp; \
  //cout << *p << endl; \
  p++; 
}

Once you have done this, you can edit your generator function:

完成此操作后,可以编辑生成器函数:

void generator(int size){
  int input_size = n[size];
  int *p, *p2; //create a pointer point to the arrays which we want to manipulate.

  switch (input_size) {
    case 100:
      MYCODE(n0);
      break;
    case 500:
      MYCODE(n1);
      break;
    // similiar for 1000, 2000, 5000, 8000, ...
  }
}

Big big advantage, when you later find out that its not while(x != 0) but while(x > 0) or something like that.. Comes in handy. When macros are not enough (e.g. typing becomes an issue), you can move on with C++ Templates that can handle different type code generation on the fly during compilation. Very usefull stuff for big, grown codebases.

大的优势,当你稍后发现它不是while(x != 0)但是while(x > 0)或类似的东西。方便。当宏不够时(例如,键入成为一个问题),您可以继续使用c++模板,这些模板可以在编译期间处理不同类型的代码生成。对大的,成熟的代码库非常有用。

#2


2  

What about:

是什么:

Add an index:

添加一个指数:

#include <map>
....

vector<int> n = { 100, 500, 1000, 2000, 5000, 8000, 10000 }; //Different input size
const int N = 20000; //random scale
int n0[100], n1[500], n2[1000], n3[2000], n4[5000], n5[8000], n6[10000]; //initialize input arrays
int *myArray[] = { n0, n1, n2 };

// index by size
map<int,int*> index= { {100,n0}, {500,n1}, {1000,n2}, {2000,n3}, {5000,n4}, {8000,n5}, {10000,n6} }; //Different input size

Abstract the code:

摘要代码:

void all_the_things_I_did_in_the_case(int *nx,int size) {
    int input_size = n[size];
    int *p, *p2; //create a pointer point to the arrays which we want to manipulate.
    p = nx;
    p2 = nx;

        //cout << "p = n0 :" << *p << endl;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
}

and replace the ugly generator

更换难看的发电机。

void generator(int size){
    map<int,int*>::iterator it=index.find(size);
    if(it!=index.end()) {
       all_the_things_I_did_in_the_case(it->second,size);
    } else {
        cout << "Invalid input_size" << endl;
    }
}

#3


1  

There's no need to use a macro (it just generates a larger program for no good reason)... as user2357112 suggested in a comment:

没有必要使用宏(它只会生成一个更大的程序)……正如user2357112所建议的:

switch (input_size)
{
  case 100: p = n0; p2 = n0; break;
  case 500: p = n1; p2 = n1; break;
  case 1000: p = n2; p2 = n2; break;
  etc.
}

...then code your loop...

…然后代码循环……

//cout << "p = n0 :" << *p << endl;
for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
{
    int tmp = 1 + (rand() % N); //Shift right by 1.
    while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
        tmp = 1 + (rand() % N); //Regenerate the element.
    *p = tmp; // let the pointer get the value of this tmp.
    //cout << *p << endl;
    p++; //Increment the pointer to pointer to next element of the array.
}
break;

(making community wiki as not my idea)

(这不是我的主意)

#4


0  

You can make your generator as generic as insertion_sort

您可以使生成器像insertion_sort一样通用。

void generator(int *a, std::size_t size)
{
    for (std::size_t i = 0; i != size; ++i) {
        do {
            a[i]= 1 + (rand() % N);
        } while (std::find(a, a + i, a[i]) != a + i);
    }
}

To auto compute the size, you may also use:

要自动计算大小,您也可以使用:

template <std::size_t SIZE> void generator(int (&a)[SIZE]) { generator(a, size); }

and in your main use:

在你的主要用途:

generator(n0);
generator(n1);
generator(n2);
generator(n3);
generator(n4);
generator(n5);
generator(n6);

#1


-1  

These are cases for compiler macros. You really don't want to end up having to update code in 100023965-zigtillion kind of places :-)

这些是编译器宏的情况。你真的不想在100023965-zigtillion的地方更新代码:-)

U can define a macro somewhat like this at the top of your file:

可以在文件的顶部定义一个类似于此的宏:

#define MYCODE(PARAM) p = PARAM; \
p2 = PARAM; \
for (int x = 0; x != input_size; ++x) { \
  int tmp = 1 + (rand() % N); //Shift right by 1. \
  while (x != 0 && isAlreadyAdded(tmp, x, p2)) \
    tmp = 1 + (rand() % N); \
  *p = tmp; \
  //cout << *p << endl; \
  p++; 
}

Once you have done this, you can edit your generator function:

完成此操作后,可以编辑生成器函数:

void generator(int size){
  int input_size = n[size];
  int *p, *p2; //create a pointer point to the arrays which we want to manipulate.

  switch (input_size) {
    case 100:
      MYCODE(n0);
      break;
    case 500:
      MYCODE(n1);
      break;
    // similiar for 1000, 2000, 5000, 8000, ...
  }
}

Big big advantage, when you later find out that its not while(x != 0) but while(x > 0) or something like that.. Comes in handy. When macros are not enough (e.g. typing becomes an issue), you can move on with C++ Templates that can handle different type code generation on the fly during compilation. Very usefull stuff for big, grown codebases.

大的优势,当你稍后发现它不是while(x != 0)但是while(x > 0)或类似的东西。方便。当宏不够时(例如,键入成为一个问题),您可以继续使用c++模板,这些模板可以在编译期间处理不同类型的代码生成。对大的,成熟的代码库非常有用。

#2


2  

What about:

是什么:

Add an index:

添加一个指数:

#include <map>
....

vector<int> n = { 100, 500, 1000, 2000, 5000, 8000, 10000 }; //Different input size
const int N = 20000; //random scale
int n0[100], n1[500], n2[1000], n3[2000], n4[5000], n5[8000], n6[10000]; //initialize input arrays
int *myArray[] = { n0, n1, n2 };

// index by size
map<int,int*> index= { {100,n0}, {500,n1}, {1000,n2}, {2000,n3}, {5000,n4}, {8000,n5}, {10000,n6} }; //Different input size

Abstract the code:

摘要代码:

void all_the_things_I_did_in_the_case(int *nx,int size) {
    int input_size = n[size];
    int *p, *p2; //create a pointer point to the arrays which we want to manipulate.
    p = nx;
    p2 = nx;

        //cout << "p = n0 :" << *p << endl;
        for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
        {
            int tmp = 1 + (rand() % N); //Shift right by 1.
            while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
                tmp = 1 + (rand() % N); //Regenerate the element.
            *p = tmp; // let the pointer get the value of this tmp.
            //cout << *p << endl;
            p++; //Increment the pointer to pointer to next element of the array.
        }
}

and replace the ugly generator

更换难看的发电机。

void generator(int size){
    map<int,int*>::iterator it=index.find(size);
    if(it!=index.end()) {
       all_the_things_I_did_in_the_case(it->second,size);
    } else {
        cout << "Invalid input_size" << endl;
    }
}

#3


1  

There's no need to use a macro (it just generates a larger program for no good reason)... as user2357112 suggested in a comment:

没有必要使用宏(它只会生成一个更大的程序)……正如user2357112所建议的:

switch (input_size)
{
  case 100: p = n0; p2 = n0; break;
  case 500: p = n1; p2 = n1; break;
  case 1000: p = n2; p2 = n2; break;
  etc.
}

...then code your loop...

…然后代码循环……

//cout << "p = n0 :" << *p << endl;
for (int x = 0; x != input_size; ++x) //for loop to generate "input_size" number of elements.
{
    int tmp = 1 + (rand() % N); //Shift right by 1.
    while (x != 0 && isAlreadyAdded(tmp, x, p2)) //Check if the generated element is already existed.
        tmp = 1 + (rand() % N); //Regenerate the element.
    *p = tmp; // let the pointer get the value of this tmp.
    //cout << *p << endl;
    p++; //Increment the pointer to pointer to next element of the array.
}
break;

(making community wiki as not my idea)

(这不是我的主意)

#4


0  

You can make your generator as generic as insertion_sort

您可以使生成器像insertion_sort一样通用。

void generator(int *a, std::size_t size)
{
    for (std::size_t i = 0; i != size; ++i) {
        do {
            a[i]= 1 + (rand() % N);
        } while (std::find(a, a + i, a[i]) != a + i);
    }
}

To auto compute the size, you may also use:

要自动计算大小,您也可以使用:

template <std::size_t SIZE> void generator(int (&a)[SIZE]) { generator(a, size); }

and in your main use:

在你的主要用途:

generator(n0);
generator(n1);
generator(n2);
generator(n3);
generator(n4);
generator(n5);
generator(n6);