鱼C论坛

 找回密码
 立即注册
查看: 1946|回复: 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};
#include<stdio.h>
#define n 20
int main()
{
    int i,j,nums[n] = {0};
    for(i = 0;i < n;i++)
    {
        scanf("%d",&nums[i]);
    }

    for (i = 0;i < n;i++)
    {
        if(nums[i] == 0 && i + 1 < n)    // 检测到数组中的0,其后的数据均前移
        {
             for(j = i;j < n;j++)
            {
                nums[j] = nums[j + 1];
            }
        }
    }

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

void foo_c( int a[], size_t n )
{
    int* q = a;
    for( int *p=a; p!=a+n; ++p )
        if( *p != 0 )
            *q++ = *p;
    for( ; q!=a+n; ++q )
        *q = 0;
}

template<typename T,size_t N> void foo_cpp( T (&a)[zxsq-anti-bbcode-N] )
{
    std::stable_partition( a, a+N, [](T n){return n>0;} );
}

template<typename T,size_t N> void print( const T (&a)[zxsq-anti-bbcode-N] )
{
    std::copy( a, a+N, std::ostream_iterator<T>(std::cout," ") );
    std::cout << std::endl;
}

int main( void )
{
    {
        int nums[] = { 9,0,0,0,10,0,0,0,11,0,12,0,13,0,14,0,15,0,16,0 };
        foo_c( nums, sizeof(nums)/sizeof(*nums) );
        print( nums );
    }
}
想知道小甲鱼最近在做啥?请访问 -> 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作为返回元素
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

int main()
{
        int i,j,k;
        int num[N] = {0};
        int * p = num;

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

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

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

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

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

朋友,我看不懂C++
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

我求助的是,他给的那个答案,什么时间复杂度,空间复杂度呀,那些乱七八糟的,请帮改写成他的答案那种形式,谢谢!
想知道小甲鱼最近在做啥?请访问 -> 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

谢谢你指出的错误,我调试时没有那么多的0,而且还是连续的0,为此,我修改了程序,将第13句到20句修改为:
        if(nums[i] == 0)    // 检测到数组中的0,其后的非0数据均前移
        {
            for(j = i + 1;j < n -1;j++)
            {
                if(nums[j] != 0)
                                {
                                        nums[i] = nums[j];
                                        nums[j] = 0;
                                        break;
                                }
            }
        }

这个代码,简单明了,没有你的那个复杂。还是请帮按给出的答案,写一个,谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-22 19:29:38 | 显示全部楼层
这么执着,好吧。满足你。
#include <stdio.H>
#define N 20

int main()
{
        int i,j;
        int num[N] = {0};
        int buffer[N] = {0};

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


        for(i=0,j=0 ; i < N ; i ++)
        {
                if(num[i] != 0)
                {
                        buffer[j++] = num[i];
                }
        }

        for(i=0 ; i<N ;i++)
        {
                num[i] = buffer[i];
                printf("%d,",num[i]);
        }

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


你的代码你还是好好测一下吧,我的直觉是不一定行。关键是
if(num[i] == 0)    //==0时 i 不要自增,道理我前面已经说过了。
{

}
else
{
   i++;
}
想知道小甲鱼最近在做啥?请访问 -> 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以后,再重复上面的动作。。。。。。
想知道小甲鱼最近在做啥?请访问 -> 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

你要的那个跟答案一样的方法在上一楼.
想知道小甲鱼最近在做啥?请访问 -> 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};
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

这是C++代码,
vector<int> xxx;就是定义一个数组
想知道小甲鱼最近在做啥?请访问 -> 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;
                         }
                 }
        }
}

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

现在不是这个问题,朋友,是他给的答案如何实现
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

是的呀,这么一个简单的问题,他为什么给出那么复杂的答案?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

朋友,我给出了两个解法,你随便调一个就行啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

你认为复杂,是因为你不懂C++。人家用C++写,不违背题意吧,真纠结!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

#include

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

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

我不懂C++,就算收藏吧,等以后学习了C++,再来研究每一条语句的功用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-12 19:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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