我正在尝试编写一个函数,将所有数字从数组的开头移动到结尾。订单不应该改变。
例如我有这个数组:
1,2,3,4,5,0,0,0,0
我想将其更改为:
0,0,0,0,1,2,3,4,5
我已经写了一个版本,但它无法保留订单。 (array []是原始的,[]是排序的)
#include <stdio.h>
#define SIZE_MAX 20
int main()
{
int array[SIZE_MAX] = {1, 2, 3, 4, 5, 0, 0, 0, 0};
int a[SIZE_MAX];
int i;
int p = 0;
for (i = SIZE_MAX-1; i >= 0; i--, p++)
{
a[i] = array[p];
}
for (i = 0; i < SIZE_MAX; i++)
{
printf("%d", a[i]);
}
}
答案 0 :(得分:4)
一种选择是循环遍历数组两次,首先复制零,然后复制其余值:
#include <stdio.h>
#define SIZE_MAX 10
int main()
{
int array[SIZE_MAX] = {1, 2, 0, 0, 3, 4, 5, 0, 0, 0};
int a[SIZE_MAX];
int i;
int p = 0;
for (i = 0; i < SIZE_MAX; ++i) {
if (array[i] == 0) {
a[p++] = 0;
}
}
for (i = 0; i < SIZE_MAX; ++i) {
if (array[i] != 0) {
a[p++] = array[i];
}
}
for (i = 0; i < SIZE_MAX; i++) {
printf("%d", a[i]);
}
}
我将SIZE_MAX
更改为10,以便它与数组中的元素数相匹配。
答案 1 :(得分:3)
如果你需要在开头的所有0
和其他数字相同的顺序尝试这个:
#include <stdio.h>
#define SIZE_MAX 9
int main()
{
int array[SIZE_MAX] = {1, 2, 3, 4, 5, 0, 0, 0, 0};
int a[SIZE_MAX];
int i;
int temp[SIZE_MAX];
int ind1=0,ind2=0;
// separating all the 0's and store it at the beginning
for (i = 0; i < SIZE_MAX; i++)
{
if(array[i]==0)
a[ind1++]=0;
else
temp[ind2++]=array[i];
}
// storing rest of the numbers in order
for (i = 0; i < ind2; i++)
{
a[ind1++]=temp[i];
}
for (i = 0; i < SIZE_MAX; i++)
{
printf("%d", a[i]);
}
}
注意:
首先我将所有0存储在结果数组中,同时所有非零值都存储在temp
数组中。
之后,我刚刚将temp
数组合并到结果数组中。
答案 2 :(得分:3)
句子“我正在尝试编写一个函数,它将所有数字从数组的开头移动到它的结尾。”听起来应该在适当的地方完成 - 事实证明这个问题很容易做到就地算法。请注意,与此处的其他算法不同,这只扫描数组一次,并将数组写入一次。在这里,我把它写成了一个函数:
void relocate_zeroes(size_t length, int *array) {
int *target = array + length - 1;
int *source = target;
for (; source >= array; source--) {
if (*source) {
*target-- = *source;
}
}
while (target >= array) {
*target-- = 0;
}
}
基本上我们从头到尾扫描一次源数组;如果我们遇到一个非零整数,我们将它重新定位在前一个非零整数之前。扫描完整个数组后,基数(array
)和target
之间的区域将填充零。
在开始时,target
和source
都指向数组的最后一个值;如果*source
不为0,我们会将*target
替换为*source
;也就是说,如果最后一个元素不为零,我们自己替换它并减少target
和source
指针;如果最后一个元素为0,我们不会将其复制到任何地方,只会减少source
指针;最后我们以这种方式继续复制了所有非零元素,我们可以用零填充剩余的数组元素。
鉴于计划:
#define SIZE_MAX 9
int main() {
int array[SIZE_MAX] = {1, 0, 2, 3, 0, 4, 0, 0, 5};
int i;
relocate_zeroes(SIZE_MAX, array);
for (i = 0; i < SIZE_MAX; i++) {
printf("%d ", array[i]);
}
}
输出
0 0 0 0 1 2 3 4 5
如果2阵列版本需要,那么这也很容易修改:
void relocate_zeroes(size_t length, int *source_array, int *target_array) {
int *target = target_array + length - 1;
int *source = source_array + length - 1;
for (; source >= source_array; source--) {
if (*source) {
*target-- = *source;
}
}
while (target >= target_array) {
*target-- = 0;
}
}
答案 3 :(得分:1)
整数 fullArray[] = { 1, 10, 20, 0, 59, 63, 0, 88, 0 };
for (int i = 0; i <= fullArray.length - 1; i++) {
if (fullArray[i] == 0 && i > 0) {
int temp = fullArray[i - 1];
if (temp != 0) {
fullArray[i - 1] = 0;
fullArray[i] = temp;
i = -1;
}
}
}
System.out.println(Arrays.asList(fullArray).toString());
答案 4 :(得分:0)
这是使用swap()
的就地方法#include <stdio.h>
#define SIZE_MAX 20
swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
moveZerosLeft(int length, int *array)
{
int i = 0;
int cur = length - 1;
for( i = length - 1; i >= 0; --i)
if(array[i] != 0)
{
swap(&array[i], &array[cur--]);
}
}
int main()
{
int array[SIZE_MAX] = {1, 2, 3, 4, 5, 0, 0, 0, 0};
int i;
int length = 9;
moveZerosLeft(length, array);
// display the result
for(i = 0; i < length; i++)
{
printf("%d ", array[i]);
}
}
我们从阵列的右侧扫描到左侧。当我们看到一个非零值时,我们将它与我们之前看到的零交换。
此方法只需要扫描一次数组。
答案 5 :(得分:0)
public class Demo{
public static void moveZeros() {
int[] num = {1, 0, 0 , 6, 7, 0};
int temp=-1;
for (int i = 0; i < num.length;i++)
{
if(num[i]!=0)
{
++temp;
if(num[temp] ==0){
int val = num[i];
num[i]=num[temp];
num[temp]=val;
}
else
{
num[temp]=num[i];
}
}
}
}
public static void main(String args[])
{
Demo.moveZeros();
}
}