标题:小弟这里有个程序代码:关于排序并确定各数值原始位置,请各位指导下,先谢 ...
只看楼主
晓亮2015
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2013-11-5
结帖率:33.33%
已结贴  问题点数:10 回复次数:8 
小弟这里有个程序代码:关于排序并确定各数值原始位置,请各位指导下,先谢谢啦!
/*说明:我这里有一个5*5的数组(实际数组为1024*1024,这里只是为了验证算法的可行性),现在想从中找出9个最大的数值并存入3*3的数组中,并且要记录这9个数值在原来5*5数组中的位置,行列值存入r[],c[],同时保持这些行列值在原始5*5数组中前后相对位置不变(不知道说清楚了么),小弟编了一个程序,但是运行起来一直有问题,的确没辙了,想请教下大家!
还请指教下!
算法思路如下:先由小到大排序,同时记录它们在5*5数组中最原始的位置r[],c[];然后结合这些位置和原始5*5数组,找到最大的9个数值按前后相对位置不变的原则存入bb[][]中。
如果大家有其他的思路,也请指导下!多谢啦!
*/

// paixu_0.cpp : Defines the entry point for the console application.

#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>

int main(int argc, char* argv[])
{
int aa[5][5]={ {4,12,54,45,23},
    {6,34,32,54,64},
    {67,34,54,32,43},
    {12,43,56,43,1},
    {5,56,78,98,15}
    };
    int i,j,temp,*p,ia,ib,ja,jb,k,m,n,*q;
    int a[5][5],r[25],c[25],bb[3][3];
    int rc,ra,ca,counts;
//****************************************************//
    //------数组的复制-----//
    for(ia=0;ia<5;ia++)
    {    for(ib=0;ib<5;ib++)
        {a[ia][ib]=aa[ia][ib];
        printf("%3d",a[ia][ib]);
        }
        printf("\n");
    }
    printf("\n");
//**********************************************************//
    //------------数组的排序--------------//
    p = &a[0][0];
    q=&aa[0][0];
    counts=0;ra=0;ca=0;rc=0;
    for(i=0;i<25-1;i++)
    {
        for(j=0;j<25-i-1;j++)
        {   
            ra=counts/5;
            ca=counts%5;
            counts++;

            if(*(p+j) > *(p+j+1))
            {   
                temp = *(p+j);
                *(p+j)=*(p+j+1);
                *(p+j+1)=temp;
            //    printf("%3d",a[i][j]);
                if(j>0)
                {    *q=*(p+j-1);
                    if(*(q)!=*(p+j+1))
                    {
                    r[rc]=ra;
                    c[rc]=ca;   
                    }
                }
                else {
                r[rc]=ra;
                c[rc]=ca;
                }
            }
        }
    //    printf("\n");
        rc++;
    }
//此处是整个程序中最为关键的地方:一方面进行二维数据的排序,从小到大;
//另一方面对每一个排序的数据记录它在5*5二维数组中最原始的位置,并将行列分别存入数组r[]和c[]中!
//*****************************************************************************************************//
    //-------输出排序后的数据----------//
    for(i=0;i<5;i++)
    {
        for(j=0;j<5;j++)
        {
            printf("%3d",a[i][j]);
        }
        printf("\n");
    }
    //--------提取其中3*3的peak并存入bb[]中----------//
    for(ja=0;ja<5;ja++)
        for(jb=0;jb<5;jb++)
        {
            for(k=0;k<9;k++)
            {
                if(ja==r[k]&&jb==c[k])
                {
                for(m=0;m<3;m++)
                    for(n=0;n<3;n++)
                        bb[m][n]=aa[ja][jb];
                }
            }
        }
//结合排序得到的最大的3*3个数据的位置求出相应的3*3矩阵,并存入bb[][]中!
//这是本程序的最终目的:即从5*5矩阵中找出3*3的最大的9个数据,同时记录他们的位置,并存入bb[][]
//(要求这9个数据在aa中的前后位置关系不能更改,即:如果78在aa中前面是56,后面是98,
//那么bb中数据的存储顺序仍然是这样的(56,78,98),不能为(67、78、98)等)
//***********************************************************************************************//
    //--------输出3*3peak数据-------//
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            printf("%3d ",bb[i][j]);
        }
        printf("\n");
    }
    return 0;
}
搜索更多相关主题的帖子: 可行性 最大的 记录 
2013-11-08 10:25
embed_xuel
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:58
帖 子:3845
专家分:11385
注 册:2011-9-13
得分:2 
没法看

总有那身价贱的人给作业贴回复完整的代码
2013-11-08 10:28
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:2 
听不懂,比如
5 6 7 8 9
4 0 0 0 0
3 0 0 0 0
2 0 0 0 0
1 0 0 0 0
你想得到啥样的3x3矩阵?
2013-11-08 13:42
qunxingw
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:24
帖 子:1676
专家分:7295
注 册:2011-6-30
得分:2 
567
894
321

www.qunxingw.wang
2013-11-08 14:18
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
得分:2 
哈哈,OK了.
用一个包含9个指针数组, 标记9个最大值的位置.
 首先找到最大值,
 然后再找剩下的, 在找的时候, 判断数据是否已经标记.
程序代码:
#include <stdio.h>

int main()
{
    int from[5][5] = {1,2,30,4,5,6,7,8,9,10,11,12,                 
        13,14,15,16,17,18,19,20,21,22,23,24,25};
    int max;                  // 找最大值
    int *p[10] = {NULL};      // 用来标记9个数据的位置, 大小要比需要找的个数大1 初始化为NULL
    int i, j, k, m;           // for循环用
    int to[3][3];            
    int r[9], c[9];

   // 首先找出最大值.
    max = from[0][0];
    p[0] = &from[0][0];            // 标记最大值位置
    for (i = 0; i < 5; ++i)
        for (j = 0; j < 5; ++j)       
            if (max < from[i][j]){
                max = from[i][j];
                p[0] = &from[i][j];
            }

    max = from[0][0];
    for (m = 1; m < 9; m++){           // 找其它8个
        for(i = 0; i < 5; i++)
            for (j = 0; j < 5; j++)                                
                if (max < from[i][j]){                          
                    for (k = 0; p[k] != &from[i][j] && p[k]; k++)      // 判断是否已标记
                        ;
                    if (!p[k]) {                                  //  p[k]为NULL, 说明没有标记
                        max = from[i][j];                         //  记这个数为max
                        p[m] = &from[i][j];                       // 标记地址.
                    }
                }
        max = from[0][0];
        }

    // 根据标记找行和列的值
    for (i = 0, k = 0; i < 5; i++)
        for (j = 0; j < 5; j++)
            for (m = 0; m < 9; m++)
                if (p[m] == &from[i][j]) {
                    r[k] = i;
                    c[k] = j;
                    k++;
                }
    // 根据标记把数据存到目标数组
    for (i = 0, m = 0; i < 3; ++i)
        for (j = 0; j < 3; ++j, m++) {
            to[i][j] = *(p[m]);
            printf("%d  ", to[i][j]);    // 验证输出.
        }
    putchar('\n');
    for (k = 0; k < 9; ++k)
        printf("%d %d\n", r[k], c[k]);  // 验证输出
   
    putchar('\n');
    return 0;
}
                              


我的算法很耗时, 希望知道优化的前辈指点指点.
2013-11-08 14:20
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
我用的是标准C语法,如果你的编译器不支持标准的C语言,自己改一下
程序代码:
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int val;
    int r, c;
} foo;

int compare1( const void* a, const void* b )
{
    int ret = ((foo*)b)->val - ((foo*)a)->val;
    if( ret ) return ret;
   

    ret = ((foo*)a)->r - ((foo*)b)->r;
    if( ret ) return ret;
    return ((foo*)a)->c - ((foo*)b)->c;
}

int compare2( const void* a, const void* b )
{
    int ret = ((foo*)a)->r - ((foo*)b)->r;
    if( ret ) return ret;
    return ((foo*)a)->c - ((foo*)b)->c;
}

int main()
{
    const int a[5][5] = {  4, 12, 54, 45, 23
                         ,  6, 34, 32, 54, 64
                         , 67, 34, 54, 32, 43
                         , 12, 43, 56, 43,  1
                         ,  5, 56, 78, 98, 15 };
    const size_t maxn = 9;


    // 转化为一维数组并排序(其实不需要排序,但C标准库中没有std::nth_element)
    const size_t R = sizeof(a)/sizeof(a[0]);
    const size_t C = sizeof(a[0])/sizeof(a[0][0]);
    const size_t N = R*C;
    const size_t M = (maxn<N?maxn:N);
    foo* buf = malloc( N*sizeof(foo) );
    for( size_t i=0; i!=N; ++i )
    {
        buf[i].r = i/C;
        buf[i].c = i%C;
        buf[i].val = a[i/C][i%C];
    }
    qsort( buf, N, sizeof(foo), &compare1 );
    qsort( buf, M, sizeof(foo), &compare2 );

    // 输出前maxn大
    for( size_t i=0; i!=M; ++i )
        printf( "a[%u][%u] = %d\n", (unsigned)buf[i].r, (unsigned)buf[i].c, buf[i].val ); // 防止不支持"%zu"

    free( buf );

    return 0;
}

2013-11-08 14:25
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
说明一下
qsort( buf, N, sizeof(foo), &compare1 ); 就是将5x5数组从大到小排序,如果数值相同,在原数组中位置靠前的,在排序后的数组中也位置靠前。
qsort( buf, M, sizeof(foo), &compare2 ); 就是将上面排序好的数组前9个重排序,排序规律为:在原数组中位置靠前的,在排序后的数组中也位置靠前。
2013-11-08 14:29
pangshch
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:2
帖 子:443
专家分:1966
注 册:2013-4-9
得分:0 
回复 6楼 rjsp
膜拜.................
我用个指针数组都心惊肉跳的,还老出错.
前辈就这么轻描淡写地丢出函数指针了.
这库函数我都没见过..
还有这思路......
我只能说:学习了.
2013-11-08 14:54
ljx小子
Rank: 8Rank: 8
来 自:星星
等 级:蝙蝠侠
威 望:2
帖 子:222
专家分:916
注 册:2013-10-7
得分:2 
学习了!!!!!!

。。。。。。。。。。。
2013-11-08 17:33



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-423223-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.056843 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved