C++ 将值插入标准c+的正确索引(升序)+;排列
我需要将两个值C++ 将值插入标准c+的正确索引(升序)+;排列,c++,arrays,C++,Arrays,我需要将两个值num1=50和num2=80插入到按升序排序的数组中。我不能使用动态数组或列表。也没有结构或类。这是一个课堂作业,所以我必须遵循指南。教授建议我创建一个新数组,newarray并从原始numarray复制值,直到达到一个条件,提示将数字按升序插入。我将循环设置为按填充newarray所需的次数运行,并设置条件以检查numarray中的前一个数字是否小于num,以及下一个值是否大于num。数字被插入到正确的位置,但是,插入新值会覆盖该位置的值。 我以为 newarray[newin
num1=50
和num2=80
插入到按升序排序的数组中。我不能使用动态数组或列表。也没有结构或类。这是一个课堂作业,所以我必须遵循指南。教授建议我创建一个新数组,newarray
并从原始numarray
复制值,直到达到一个条件,提示将数字按升序插入。我将循环设置为按填充newarray
所需的次数运行,并设置条件以检查numarray
中的前一个数字是否小于num
,以及下一个值是否大于num
。数字被插入到正确的位置,但是,插入新值会覆盖该位置的值。
我以为
newarray[newindex]=num1;
newarray[newindex+1]=numarray[newindex]
将插入的值写入当前索引,然后将numaray[newindex]
写入其后面的索引
我将附加下面的函数。除numarray外,函数中的所有内容都是自包含的,它的排序值最多为100。提前谢谢。也许离开一会儿能帮我弄明白
void insertArray(int* numarray) {
int num1 = 50;
int num2 = 80;
int counter = 0;
int newarray[103] = {};
for (int newindex = 0; newindex < 103; newindex++) {
if (numarray[newindex] <= num1 && numarray[newindex+1] > num1) {
newarray[newindex] = num1;
newarray[newindex+1] = numarray[newindex];
}
else if (numarray[newindex] <= num2 && numarray[newindex+1] > num2) {
newarray[newindex] = num2;
newarray[newindex+1] = numarray[newindex];
}
else {
newarray[newindex] = numarray[newindex];
}
cout << newarray[newindex] << endl;
}
}
int main() {
int numarray[100] = {};
randomgenerator();
read(numarray);
printArray(numarray);
searchArray(numarray);
Delete(numarray);
sortArray(numarray);
insertArray(numarray);
return 0;
}
void insertArray(int*numarray){
int num1=50;
int num2=80;
int计数器=0;
int newarray[103]={};
对于(int newindex=0;newindex<103;newindex++){
if(numarray[newindex]num1){
newarray[newindex]=num1;
newarray[newindex+1]=numarray[newindex];
}
else if(numarray[newindex]num2){
newarray[newindex]=num2;
newarray[newindex+1]=numarray[newindex];
}
否则{
newarray[newindex]=numarray[newindex];
}
在我看来,这种方法大体上是错误的
新数组应该在函数main中声明,插入一个数字后输出
该函数不应同时插入两个数字。它只应插入一个数字,但调用次数应与在数组中插入新数字的次数相同
当目标数组和源数组是同一个数组时,可以调用该函数来插入值
因此,我建议采用下面演示程序中所示的以下方法
#include <iostream>
void insert( const int *a1, size_t n, int *a2, int value )
{
const int *p = a1 + n;
a2 += n;
while ( ( p != a1 ) && ( value < *( p - 1 ) ) ) *a2-- = *--p;
*a2-- = value;
while ( p != a1 ) *a2-- = *--p;
}
int main()
{
int a1[] = { 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 };
const size_t N = sizeof( a1 ) / sizeof( *a1 );
int a2[N + 2];
insert( a1, N, a2, 50 );
for ( size_t i = 0; i < N + 1; i++ )
{
std::cout << a2[i] << ' ';
}
std::cout << '\n';
insert( a2, N + 1, a2, 80 );
for ( size_t i = 0; i < N + 2; i++ )
{
std::cout << a2[i] << ' ';
}
std::cout << '\n';
return 0;
}
至于你的代码,比如这个循环
for (int newindex = 0; newindex < 103; newindex++) {
if (numarray[newindex] <= num1 && numarray[newindex+1] > num1) {
//...
它的产量是
5 15 25 35 45 50 55 65 75 85 95
5 15 25 35 45 50 55 65 75 80 85 95
5 15 25 35 45 50 55 65 75 80 85 95
我完全同意你的新数组应该在调用者中声明,并作为参数传递给你的插入函数。如果你使用的是POA(普通的旧数组),这是必须的当函数返回时,在insert函数中声明的新POA将不再存在。您始终可以在insert函数中为数组分配存储并返回指向已分配块的指针,但即使如此,如果您希望将insert函数类型保留为void
,也可以在调用者中声明并传递它作为一个参数
有许多方法可以按排序顺序插入到新数组中,对于小数组(比如1000个左右的元素)都可以但是,由于原始数组已经排序,因此对于较大的数组,可以利用这一事实编写一个效率更高几个数量级的例程。使用排序数组的有效方法类似于b搜索
在这里,您只需将要插入的值与数组中的中间元素进行比较。如果该值大于数组中的第一个元素且小于中间元素,则您知道将在原始数组的前1/2处插入该值。您可以将整个数组的第二个1/2复制到新数组的中间元素+1处t点并重复
如果该值大于中间元素,则可以将原始数组的整个前1/2复制到新数组的开头,并在数组的第二个1/2中继续搜索
当您的值小于或等于子数组中的第一个元素时,您已找到插入点,可以将新数组中的值设置为要插入的值,并从下一个索引开始将子数组的其余部分复制到新数组中
类似地,如果您的值大于子数组的结束值,则可以将新数组中范围结束处的值插入该值,然后将剩余值从原始值复制到新数组中范围的开始处
这样做可以显著减少查找插入点所需的最坏情况下的迭代次数,并允许您使用效率更高的副本来填充插入值上方和下方的新数组元素。例如,对于1000000元素数组,如果您在末尾开始迭代并朝着从一开始,实际新元素是数组中的第一个元素,您将迭代1000000次以插入新值,并将剩余元素从原始数组复制到新数组
与上面描述的方法相比,在这种方法中,您有效地将原始数据平分为子阵列,最坏的情况是最多20次迭代以找到插入点,2次复制以复制插入值下方和上方的元素
虽然您可以在一个函数中完成所有操作,但它有助于将函数拆分为两个单独的函数。一个函数用于查找新元素的插入位置,该新元素将进行递归调用(比如调用它findinspos
,它根本不需要新数组作为参数),另一个函数(说insensected
,调用findinspos
,然后复制其余元素)
这些措施可实施为:
/* returns index where v should be inserted in a for a given
* start index and an array of nelem elements.
*/
int findinspos (const int *a, int start, int nelem, int v)
{
int mid = (start + nelem) / 2;
if (v <= a[start]) /* exit conditon ins at start */
return start;
else if (a[nelem - 1] < v) /* exit condition ins at end */
return nelem;
else if (v < a[mid]) /* v in 1st 1/2 subarray */
return findinspos (a, start, mid, v);
else /* v in 2nd 1/2 subarray */
return findinspos (a, mid, nelem, v);
}
/* inserts v in sorted positon within the nelem elements of a with
* the results stored in b.
*/
void insinsorted (const int *a, int nelem, int v, int *b)
{
int inspos = findinspos (a, 0, nelem, v); /* get insert positon */
b[inspos] = v; /* set value at inspos in new array */
if (inspos == 0) /* if ins at start copy a beginning at next element */
memcpy (b + 1, a, nelem * sizeof *b);
else if (inspos == nelem) /* if at end, copy a to b */
memcpy (b, a, nelem * sizeof *b);
else { /* otherwise, copy begin and end of a to b */
memcpy (b, a, inspos * sizeof *b);
memcpy (b + inspos + 1, a + inspos, (nelem - inspos) * sizeof *b);
}
}
(5 15 25 35 45 50 55 65 75 80 85 95
/* returns index where v should be inserted in a for a given
* start index and an array of nelem elements.
*/
int findinspos (const int *a, int start, int nelem, int v)
{
int mid = (start + nelem) / 2;
if (v <= a[start]) /* exit conditon ins at start */
return start;
else if (a[nelem - 1] < v) /* exit condition ins at end */
return nelem;
else if (v < a[mid]) /* v in 1st 1/2 subarray */
return findinspos (a, start, mid, v);
else /* v in 2nd 1/2 subarray */
return findinspos (a, mid, nelem, v);
}
/* inserts v in sorted positon within the nelem elements of a with
* the results stored in b.
*/
void insinsorted (const int *a, int nelem, int v, int *b)
{
int inspos = findinspos (a, 0, nelem, v); /* get insert positon */
b[inspos] = v; /* set value at inspos in new array */
if (inspos == 0) /* if ins at start copy a beginning at next element */
memcpy (b + 1, a, nelem * sizeof *b);
else if (inspos == nelem) /* if at end, copy a to b */
memcpy (b, a, nelem * sizeof *b);
else { /* otherwise, copy begin and end of a to b */
memcpy (b, a, inspos * sizeof *b);
memcpy (b + inspos + 1, a + inspos, (nelem - inspos) * sizeof *b);
}
}
#include <iostream>
#include <cstring>
/* returns index where v should be inserted in a for a given
* start index and an array of nelem elements.
*/
int findinspos (const int *a, int start, int nelem, int v)
{
int mid = (start + nelem) / 2;
if (v <= a[start]) /* exit conditon ins at start */
return start;
else if (a[nelem - 1] < v) /* exit condition ins at end */
return nelem;
else if (v < a[mid]) /* v in 1st 1/2 subarray */
return findinspos (a, start, mid, v);
else /* v in 2nd 1/2 subarray */
return findinspos (a, mid, nelem, v);
}
/* inserts v in sorted positon within the nelem elements of a with
* the results stored in b.
*/
void insinsorted (const int *a, int nelem, int v, int *b)
{
int inspos = findinspos (a, 0, nelem, v); /* get insert positon */
b[inspos] = v; /* set value at inspos in new array */
if (inspos == 0) /* if ins at start copy a beginning at next element */
memcpy (b + 1, a, nelem * sizeof *b);
else if (inspos == nelem) /* if at end, copy a to b */
memcpy (b, a, nelem * sizeof *b);
else { /* otherwise, copy begin and end of a to b */
memcpy (b, a, inspos * sizeof *b);
memcpy (b + inspos + 1, a + inspos, (nelem - inspos) * sizeof *b);
}
}
int main (int argc, char **argv) {
int a[] = { 5, 15, 25, 35, 45, 55, 65, 75, 85, 95 },
nelem = sizeof a / sizeof *a,
*b = new int[nelem+1] {},
v = argc > 1 ? strtol (argv[1], NULL, 0) : 4;
for (int i = 0; i < nelem; i++)
std::cout << " " << a[i];
std::cout << '\n';
insinsorted (a, nelem, v, b);
for (int i = 0; i < nelem + 1; i++)
std::cout << " " << b[i];
std::cout << '\n';
delete[] b;
}
void copyAndInsert(int* numarray, int size, int* newarray, int num1, int num2)
{
if (num1 > num2) { std::swap(num1, num2); } // ensure we write the smaller number first
int * num1pos = std::lower_bound(numarray, numarray + size, num1); // find where to put num1
int * new1pos = std::copy(numarray, num1pos, newarray); // copy the numbers less than num1
*new1pos++ = num1; // copy num1 and move past it
int * num2pos = std::lower_bound(num1pos, numarray + size, num2); // find where to put num2
int * new2pos = std::copy(num1pos, num2pos, new1pos); // copy the numbers between num1 and num2
*new2pos++ = num2; // copy num2 and move past it
std::copy(num2pos, numarray + size, new2pos); // copy the numbers greater than num2
}
int main() {
int numarray[100] = {};
int newarray[102] = {};
randomgenerator();
read(numarray);
printArray(numarray);
searchArray(numarray);
Delete(numarray);
sortArray(numarray);
copyAndInsert(numarray, 100, newarray, 50, 80);
return 0;
}
int* lower_bound(int* first, int* last, int value)
{
int count = last - first;
while (count > 0) {
int step = count / 2;
int* it = first + step;
if (*it < value) {
first = ++it;
count -= step + 1;
}
else {
count = step;
}
}
return first;
}
int* copy(int* first, int* last, int* d_first)
{
while (first != last) {
*d_first++ = *first++;
}
return d_first;
}
#include<algorithm>
void insertArray(int* numarray) {
int num1 = 50;
int num2 = 80;
std::vector<int> numbersToAdd{num1, num2};
//make sure numbersToAdd is sorted
std::sort(begin(numbersToAdd), end(numbersToAdd));
int newarray[102] = {};
std::merge(numarray, numarray + 100, begin(numbersToAdd), end(numbersToAdd), newarray);
}