鱼C论坛

 找回密码
 立即注册
查看: 2421|回复: 25

[已解决]C语言越学越不懂了,请教

[复制链接]
发表于 2020-10-21 17:44:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 乐乐学编程 于 2020-10-21 17:47 编辑

这个题目我不看答案会做,看答案就不会了,请求帮助

【每日一练 第17天】
给定一个数组nums,写一个函数,将数组中所有的0挪到数组的末尾,而维持其他所有非0元素的相对位置。

举例: nums = [0, 1, 0, 3, 12],函数运?后结果为[1, 3, 12, 0, 0]

第17天答案:

思路:创建一个临时数组nonZeroElements,遍历nums,将nums中非0元素赋值到nonZeroElements中,而后按顺序将nonZeroElements赋值到nums上,未遍历的元素置0;

代码如下:
1// 时间复杂度: O(n)
2// 空间复杂度: O(n)
3class Solution {

4public:

5    void moveZeroes(vector<int>& nums) {

6
7        vector<int>
nonZeroElements;

8

9        // 将vec中所有非0元素放入nonZeroElements中
10        for(int i = 0 ; i <  nums.size() ; i ++)

11            if(nums[ i ])

12
nonZeroElements.push_back(nums[ i] );

13

14        // 将nonZeroElements中的所有元素依次放入到nums开始的位置

15        for(int i = 0 ; i < nonZeroElements.size() ; i ++)

16            nums[ i ] = nonZeroElements[ i ];

17

18        // 将nums剩余的位置放置为0

19        for(int i = nonZeroElements.size() ; i < nums.size() ; i ++)

20            nums[ i ] = 0;

21    }

22};

  1. #include<stdio.h>
  2. #define n 20
  3. int main()
  4. {
  5.     int i,j,nums[n] = {0};
  6.     for(i = 0;i < n;i++)
  7.     {
  8.         scanf("%d",&nums[i]);
  9.     }

  10.     for (i = 0;i < n;i++)
  11.     {
  12.         if(nums[i] == 0 && i + 1 < n)    // 检测到数组中的0,其后的数据均前移
  13.         {
  14.              for(j = i;j < n;j++)
  15.             {
  16.                 nums[j] = nums[j + 1];
  17.             }
  18.         }
  19.     }

  20.     for(i = 0;i < n;i++)
  21.     {
  22.         printf("%d ",nums[i]);
  23.     }
  24.     printf("\n");
  25. }
复制代码
最佳答案
2020-10-25 00:52:50
本程序需要在DEV_C++的菜单--->工具--->编译选项--->编译时加入命令前打勾,并在下面的加入框中加入:-std=c++11


  1. #include <iostream>
  2. #include <iterator>
  3. #include <algorithm>

  4. void foo_c( int a[], size_t n )
  5. {
  6.     int* q = a;
  7.     for( int *p=a; p!=a+n; ++p )
  8.         if( *p != 0 )
  9.             *q++ = *p;
  10.     for( ; q!=a+n; ++q )
  11.         *q = 0;
  12. }

  13. template<typename T,size_t N> void foo_cpp( T (&a)[N] )
  14. {
  15.     std::stable_partition( a, a+N, [](T n){return n>0;} );
  16. }

  17. template<typename T,size_t N> void print( const T (&a)[N] )
  18. {
  19.     std::copy( a, a+N, std::ostream_iterator<T>(std::cout," ") );
  20.     std::cout << std::endl;
  21. }

  22. int main( void )
  23. {
  24.     {
  25.         int nums[] = { 9,0,0,0,10,0,0,0,11,0,12,0,13,0,14,0,15,0,16,0 };
  26.         foo_c( nums, sizeof(nums)/sizeof(*nums) );
  27.         print( nums );
  28.     }
  29. }

复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-10-21 18:49:15 | 显示全部楼层
我用C++简单实现了以下,写的比较渣,欢迎交流

#include <iostream>
#include <vector>
using namespace std;

double* move(double arr[], int len)
{
    vector<double> vct;
    for(int i=0; i<len; i++)
    {
        if(arr[i] != 0)
            vct.push_back(arr[i]);
    }

    double *temp = new double[len];
    for(int i=0; i<len; i++)
        temp[i] = vct[i];
    return temp;
}

int main(void)
{
    double arr[] = {2, 0, 4, 5, 6, 0, -2, -3, -4};
    double *temp = move(arr, 9);

    for(int i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
        cout << temp[i] << ", ";
    cout << endl;

    return 0;
}

其中arr是测试数据,temp作为返回元素
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-21 18:50:27 | 显示全部楼层
说真的,能用C++我就不想用C了
用C++真的太爽了,虽然还有很多没学(C++比Java难多了),但是能感觉到这种简洁性
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-21 19:33:33 | 显示全部楼层
本帖最后由 xieglt 于 2020-10-21 20:05 编辑
  1. #include <stdio.H>
  2. #define N 20

  3. int main()
  4. {
  5.         int i,j,k;
  6.         int num[N] = {0};
  7.         int * p = num;

  8.         for(i = 0 ; i < N ; i ++)
  9.         {
  10.                 scanf("%d",&num[i]);
  11.         }

  12.         for(i = 0 , j = N-1; i < j ; )
  13.         {
  14.                 if(*p == 0)
  15.                 {
  16.                         //如果要实现所谓的 O(N) 可以把这个循环换成函数内存复制 memcpy
  17.                         //memcpy(p,p+1,sizeof(int)*(j - (p - num)));
  18.                         for(k = 0 ; k < j-1 ; k ++)
  19.                         {
  20.                                 *(p + k) = *(p + k + 1);
  21.                         }

  22.                         num[j--] = 0;
  23.                 }
  24.                 //你的代码的问题出在这里, num[i] ==0 时,i 不应该自加,
  25.                 //因为如果 num[i+1] 也等于 0 ,把后面的复制到前面后,num[i] 又等于0了,而你把 i 自加了,就把这个0空过了
  26.                 else
  27.                 {
  28.                         p++;
  29.                         i++;
  30.                 }
  31.         }

  32.         for(i = 0 ; i < N ; i ++)
  33.         {
  34.                 printf("%d,",num[i]);
  35.         }

  36.         return 0;
  37. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-21 22:57:06 | 显示全部楼层
资治通鉴 发表于 2020-10-21 18:50
说真的,能用C++我就不想用C了
用C++真的太爽了,虽然还有很多没学(C++比Java难多了),但是能感觉到这种 ...

朋友,我看不懂C++
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-21 23:02:25 | 显示全部楼层

我的代码是正确的,在DEV_C++ 与 VC++6.0 中运行都是正常的

我求助的是,他给的那个答案,什么时间复杂度,空间复杂度呀,那些乱七八糟的,请帮改写成他的答案那种形式,谢谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-22 07:42:20 | 显示全部楼层
本帖最后由 xieglt 于 2020-10-22 07:48 编辑

程序不是编译通过就是对的,要多种输入测试看运行结果。左边是你的代码的运行结果。并不符合题意。
至于时间复杂度O(N),主要是指程序要经过多少次循环,比如说logn 次,n次,n*logn次,n平方次等等。
空间复杂度是指程序里有没有额外分配内存,分配了多少。原答案用到了额外的数组,空间复杂度应该是O(2n)
111.JPG
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-22 19:07:03 | 显示全部楼层
xieglt 发表于 2020-10-22 07:42
程序不是编译通过就是对的,要多种输入测试看运行结果。左边是你的代码的运行结果。并不符合题意。
至于时 ...

谢谢你指出的错误,我调试时没有那么多的0,而且还是连续的0,为此,我修改了程序,将第13句到20句修改为:


  1.         if(nums[i] == 0)    // 检测到数组中的0,其后的非0数据均前移
  2.         {
  3.             for(j = i + 1;j < n -1;j++)
  4.             {
  5.                 if(nums[j] != 0)
  6.                                 {
  7.                                         nums[i] = nums[j];
  8.                                         nums[j] = 0;
  9.                                         break;
  10.                                 }
  11.             }
  12.         }

复制代码


这个代码,简单明了,没有你的那个复杂。还是请帮按给出的答案,写一个,谢谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-22 19:29:38 | 显示全部楼层
这么执着,好吧。满足你。

  1. #include <stdio.H>
  2. #define N 20

  3. int main()
  4. {
  5.         int i,j;
  6.         int num[N] = {0};
  7.         int buffer[N] = {0};

  8.         for(i = 0 ; i < N ; i ++)
  9.         {
  10.                 scanf("%d",&num[i]);
  11.         }


  12.         for(i=0,j=0 ; i < N ; i ++)
  13.         {
  14.                 if(num[i] != 0)
  15.                 {
  16.                         buffer[j++] = num[i];
  17.                 }
  18.         }

  19.         for(i=0 ; i<N ;i++)
  20.         {
  21.                 num[i] = buffer[i];
  22.                 printf("%d,",num[i]);
  23.         }

  24.         return 0;
  25. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-22 19:32:12 | 显示全部楼层
乐乐学编程 发表于 2020-10-22 19:07
谢谢你指出的错误,我调试时没有那么多的0,而且还是连续的0,为此,我修改了程序,将第13句到20句修改为 ...


你的代码你还是好好测一下吧,我的直觉是不一定行。关键是


  1. if(num[i] == 0)    //==0时 i 不要自增,道理我前面已经说过了。
  2. {

  3. }
  4. else
  5. {
  6.    i++;
  7. }

复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2020-10-22 19:43:28 | 显示全部楼层
xieglt 发表于 2020-10-22 19:32
你的代码你还是好好测一下吧,我的直觉是不一定行。关键是

我试过了

输入:10,0,0,0,9,0,0,0,11,0,12,0,13,0,14,0,15,0,16,0
输出:10,9,11,12,13,14,15,16,0,0,0,0,0,0,0,0,0,0,0,0

检测到0以后,我让 j 指向其下一个数 j = i + 1,如果 j 遇到的是0,则循环到下一个,直至不是0为止,将这个不为0的数存入 i 这个单元中,同时将 j 的这个单元置0,以防止下次循环再调用到它,终止此次循环。i 加1以后,再重复上面的动作。。。。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-22 20:25:10 | 显示全部楼层
乐乐学编程 发表于 2020-10-22 19:43
我试过了

输入:10,0,0,0,9,0,0,0,11,0,12,0,13,0,14,0,15,0,16,0

你要的那个跟答案一样的方法在上一楼.
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-22 21:00:38 | 显示全部楼层
xieglt 发表于 2020-10-22 20:25
你要的那个跟答案一样的方法在上一楼.

我晕,将非0数暂存于一个临时数组,当然是最简单的办法啦~~他不给出下面的代码,我当然是哪个简单就用哪个方法来做题,难道我真的被出题的混蛋给骗了?又是 class,又是 public ,还 nonZeroElements.push_back 函数都出来了

我想弄清楚的是为什么他会给出下面的代码?

代码如下:
1// 时间复杂度: O(n)
2// 空间复杂度: O(n)
3class Solution {
4public:
5    void moveZeroes(vector<int>& nums) {
6
7        vector<int>
nonZeroElements;
8
9        // 将vec中所有非0元素放入nonZeroElements中
10        for(int i = 0 ; i <  nums.size() ; i ++)
11            if(nums[ i ])
12
nonZeroElements.push_back(nums[ i] );
13
14        // 将nonZeroElements中的所有元素依次放入到nums开始的位置
15        for(int i = 0 ; i < nonZeroElements.size() ; i ++)
16            nums[ i ] = nonZeroElements[ i ];
17
18        // 将nums剩余的位置放置为0
19        for(int i = nonZeroElements.size() ; i < nums.size() ; i ++)
20            nums[ i ] = 0;
21    }
22};
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-22 21:39:43 | 显示全部楼层
乐乐学编程 发表于 2020-10-22 21:00
我晕,将非0数暂存于一个临时数组,当然是最简单的办法啦~~他不给出下面的代码,我当然是哪个简单就用哪 ...

这是C++代码,
vector<int> xxx;就是定义一个数组
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-22 22:45:59 | 显示全部楼层
#inclue <iostream>
using namespace std;

void move(int arr[], int len)
{
        for(int i=0, j=-1; i<len; i++)
        {
                for(; arr[i]!=0; j++)
                {
                        if(i != j)
                        {
                                arr[j] = arr[i];
                                arr[i] = 0;
                         }
                 }
        }
}

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-22 23:20:30 | 显示全部楼层
资治通鉴 发表于 2020-10-22 22:45
#inclue
using namespace std;

现在不是这个问题,朋友,是他给的答案如何实现
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-22 23:21:30 | 显示全部楼层
xieglt 发表于 2020-10-22 21:39
这是C++代码,
vector xxx;就是定义一个数组

是的呀,这么一个简单的问题,他为什么给出那么复杂的答案?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-23 00:28:47 | 显示全部楼层
乐乐学编程 发表于 2020-10-22 23:21
是的呀,这么一个简单的问题,他为什么给出那么复杂的答案?

朋友,我给出了两个解法,你随便调一个就行啦
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-23 09:39:53 | 显示全部楼层
乐乐学编程 发表于 2020-10-22 23:21
是的呀,这么一个简单的问题,他为什么给出那么复杂的答案?

你认为复杂,是因为你不懂C++。人家用C++写,不违背题意吧,真纠结!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-23 16:46:05 | 显示全部楼层
资治通鉴 发表于 2020-10-21 18:49
我用C++简单实现了以下,写的比较渣,欢迎交流

#include

你将2楼这个程序修改一下,数组元素改为20个吧

另外,2楼这个程序,非0时输出是乱码,请改回输出0

我不懂C++,就算收藏吧,等以后学习了C++,再来研究每一条语句的功用
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-2 12:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表