标题:不可思议的运行结果...... 再讨论!
只看楼主
zhangheyuan
Rank: 1
等 级:新手上路
帖 子:74
专家分:4
注 册:2018-5-23
结帖率:85.71%
 问题点数:0 回复次数:19 
不可思议的运行结果...... 再讨论!
遇到一不可思议的问题!!!     ( 代码的适用性不重要,重要的是解决这个“不可思议”的困惑。请大家看清楚,注意区分 ii 和 jj )

 第一段代码:
*
*       插入排序算法练习
*
*Dimension AA(20)   &&数组名 有大小写之分;使用[]和()都行!
*Declare AA(20)  &&也可以。Declare和 Dimension 一样,就和EDIT命令和change命令相同一样。重定义数组,对应的元素值不变化!
**由于FoXPro数组的下标,一般是从1开始的,所有不能使用数组来完成 插入排序,当然Asort函数就可以直接排序数组。

input '请输入第1个数值型数据:' to AA1
 for ii=2 to 10    && 10个数组排序,n=10
   ii_c=transform(ii)
   input '请输入第'+ii_c+'个数值型数据:' to AA&ii_c
   AA0 = AA&ii_c
   jj=ii-1
   jj_c=transform(jj)
   do while .t.    &&为什么用 do while AA0 < AA&jj_c 出现不是预知的逻辑错误呢?
   if AA0 < AA&jj_c   && transform(0) 就是返回 '0'
     jj1_c=transform(jj+1)
     AA&jj1_c = AA&jj_c
     jj=jj-1
     jj_c=transform(jj)
    else
     exit
    endif
   enddo
   jj1_c=transform(jj+1)
   AA&jj1_c = AA0
 endfor

 for ii=1 to 10
   ii_c=transform(ii)
   ? 'AA'+ii_c+':'+transform(AA&ii_c)
 endfor


第二段代码:

input '请输入第1个数值型数据:' to AA1
 for ii=2 to 10    && 10个数组排序,n=10
   ii_c=transform(ii)
   input '请输入第'+ii_c+'个数值型数据:' to AA&ii_c
   AA0 = AA&ii_c
   jj=ii-1
   jj_c=transform(jj)
   do while AA0 < AA&jj_c    &&为什么 do while AA0 < AA&jj_c 出现逻辑错误呢?  transform(0) 就是返回 '0'
     jj1_c=transform(jj+1)
     AA&jj1_c = AA&jj_c
     jj=jj-1
     jj_c=transform(jj)
   enddo
   jj1_c=transform(jj+1)
   AA&jj1_c = AA0
 endfor

 for ii=1 to 10
   ii_c=transform(ii)
   ? 'AA'+ii_c+':'+transform(AA&ii_c)
 endfor
第一段代码和第二段代码运行结果应该是相同的呀!  为什么第二段代码出现不是预知的逻辑错误啊!不可思议,求高手解答!! 谢谢!!!

第二段代码:改为:
for ii=2 to 10    && 10个数组排序,n=10
    ii_c=transform(ii)
    input '请输入第'+ii_c+'个数值型数据:' to AA&ii_c
    AA0 = AA&ii_c
    jj=ii-1
    jj_c=transform(jj)
    AAn=AA&jj_c
    do while AA0 < AAn    &&为什么 do while AA0 < AA&jj_c 出现逻辑错误呢?  transform(0) 就是返回 '0' do whhile "条件表达式"不能使用宏代换符号 "&"  吗? 为什么 IF 条件表达式就可以呢?
     jj1_c=transform(jj+1)
      AA&jj1_c = AA&jj_c
      jj=jj-1
      jj_c=transform(jj)
      AAn=AA&jj_c
    enddo
    jj1_c=transform(jj+1)
    AA&jj1_c = AA0
  endfor

  for ii=1 to 10
    ii_c=transform(ii)
    ? 'AA'+ii_c+':'+transform(AA&ii_c)
  endfor
这样也可以运行出 预想的结果的!



高手可以试运行一下这三段代码,帮忙分析分析第二段代码错在哪里?
 
代码的适用性不重要,重要的是解决这个“不可思议”的困惑。

 这是插入排序的典型算法,巧妙引用数组 下标0的元素  AA(0)  控制循环到最后的安全退出。

 由于VFP不能引用0下标,本人采用了变量:AA0, AA1, AA2, ....,AA10  的方法模拟数组。原理是一样的,排序结果在:AA1到AA10的变量里。
 本人在多年使用VFP6.0 编程的过程,遇到过一些不可思议的问题。


搜索更多相关主题的帖子: 运行 代码 排序 数组 do 
2018-06-05 21:00
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
试试先声明定义变量 AA0, AA1, AA2, ....,AA10
2018-06-05 21:28
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
do while AA0 < AA&jj_c 这句应该没问题
这样测试没异常提示:
AA0 = 1
AA1 = 10
jj_c = "1"
DO WHILE AA0 < AA&jj_c
    ? AA0
    AA0 = AA0 + 1
ENDDO

2018-06-05 21:30
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:396
帖 子:11713
专家分:43267
注 册:2006-5-13
得分:0 
不可思议是因为尚未完全掌握。这类问题无非就是数据类型不一致或者是字符串中的前后空格产生的,仔细跟踪检查一下应该能够找到原因。

活到老,学到老! http://www. E-mail:hu-jj@
2018-06-06 08:28
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
*!*    插入排序法 所谓插入排序法乃是将一个数目插入该占据的位置。

*!*        假设我们输入的是 “5,1,4,2,3” 我们从第二个数字开始,这个数字是1,我们的任务只要看看1有没有正确的位置,我们的做法是和这个数字左边的数字来比,
*!*    因此我们比较1和5,1比5小,所以我们就交换1和5,原来的排列就变成了“1,5,4,2,3 ”

*!*        接下来,我们看第3个数字有没有在正确的位置。这个数字是4,它的左边数字是5,4比5小,所以我们将4和5交换,排列变成了 “1,4,5,2,3 "我们必须继续看4
*!*    有没有在正确的位置,4的左边是1,1比4小,4就维持不动了。

*!*        再来看第四个数字,这个数字是2,我们将2和它左边的数字相比,都比2大,所以就将2一路往左移动,一直移到2的左边是1,这时候排序变成了 “1,2,4,5,3 ”

*!*        最后,我们检查第五个数字,这个数字是3,3必须往左移,一直移到3的左边是2为止,所以我们的排列就变成了 “1,2,3,4,5 ”排序因此完成了。

*!*       所谓插入排序法,就是检查第i个数字,如果在它的左边的数字比它大,进行交换,这个动作一直继续下去,直到这个数字的左边数字比它还要小,就可以停止了。
*!*    插入排序法主要的回圈有两个变数:i和j,每一次执行这个回圈,就会将第i个数字放到左边恰当的位置去。

clear
local i,j,tmp
Dimension aa[5]
aa[1] = 5
aa[2] = 1
aa[3] = 4
aa[4] = 2
aa[5] = 3
?aa[1],aa[2],aa[3],aa[4],aa[5]
for i=2 to 5 step 1
    for j=i to 2 step -1
        if aa[j] < aa[j-1] && 右边的数比左边的数小,就交换
           tmp = aa[j]
           aa[j] = aa[j-1]
           aa[j-1] = tmp
        else
           exit && 退出是为了减少循环次数,可以不退出
        endif
    endfor
endfor
?aa[1],aa[2],aa[3],aa[4],aa[5]
2018-06-06 10:50
zhangheyuan
Rank: 1
等 级:新手上路
帖 子:74
专家分:4
注 册:2018-5-23
得分:0 
  在VFP中这个排序,确实没有实际意义,VFP有多种处理方法,谁测试过着3段代码?帮忙分析分析,从语句结构看,三段代码执行效果应该是一致的。
可就是第二段代码,运行后没有排序,出现了比预想的结果有偏差。希望高手运行、跟踪一下。看看原因。

感谢5楼兄弟 对插入排序的解释。我的插入排序算法是不交换,只是移位,把要排序的数,先放入AA0(AA零不是字母O);这样在J-1 减到最后,J为0了,也能安全退出,(相等了嘛,大于的时候向前移位)
如:   第5个数是 5  ;   AA1-AA4: 1 2  3 4 ;  先AA5->AA0,比较 1和5   1小 5大 1->AA5;在向后比较 2和5 还是5 大 2->AA4 ....3->AA3  4->AA2
这是J为0了 AA0 和5 相等了,AA1空出来了,将5送入AA1,就是插入5到 AA1 位置,就是所谓的插入排序啊!

5楼兄弟你的排序法,我觉得应该是交换排序(和冒泡排序有点相似)!     

就没人能给我个满意的解答吗?


[此贴子已经被作者于2018-6-6 21:17编辑过]

2018-06-06 21:03
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
以下是引用zhangheyuan在2018-6-6 21:03:37的发言:

      

就没人能给我个满意的解答吗?

见问题也回复了一下,但未见回应。
想要什么解答?要用VFP代码写一个“插入法”排序吗?
“不可思议”的东西有点玄,还是直接点,来点可思可议的好了。


[此贴子已经被作者于2018-6-7 08:00编辑过]

2018-06-06 22:19
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
回复 6楼 zhangheyuan
5楼的插入排序的解释是网上说的。
我看了“冒泡排序”,“插入排序”等等,在我看来,都是交换位置的。
我特意对比一下,“冒泡排序”,“插入排序”的FOR循环次数,发现,“插入排序”的实际循环次数大概是“冒泡排序”实际循环次数的一半左右(在大数据的情况下,如数组个数10000以上)
你要解释你1楼3个方法的效率问题?还是错误提示问题?
另外,在大量循环的时候,如果要效率的,最好不要用到宏运算,如果用宏,会慢很多。
2018-06-07 09:24
gs2536785678
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:45
帖 子:565
专家分:1668
注 册:2017-7-16
得分:0 
在DOS时代,没有窗口,只有代码。
排序问题是个基本功。
如今的WINDOWS时代,重点在考虑
面向对象,程序装饰。
象这个排序,只要能够使用即可。
用不到探索“冒泡”,“插入”
2018-06-07 09:38
mywisdom88
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:190
帖 子:3125
专家分:8340
注 册:2015-3-25
得分:0 
第2段程序,会出现 jj = 0,-1的情况,导致出现 aa-1这样的非法变量。要加1个限制, do while AA0 < AA&jj_c  AND jj>0
同时,由于你没有定义变量,比如 jj=0时,aa&jj 后,相当 aa0这样的没定义变量错误
由于你的数据是你自己输入的,用Input to 输入的,我测试了一下,可以输入 数值,回车,"字符"这样会导致,输入的10个内容的类型不相同,对比时,会出现错误  AA0 < AA&jj_c
另外,第2段程序,不是不会排序,交换的太多了。
对比测试,输入5个数字,分别是 5,3,1,4,2
第1段,交换7次,第2段交换9次。
CLEAR

k=0
input '请输入第1个数值型数据:' to AA1
  for ii=2 to 5    && 10个数组排序,n=10
    ii_c=transform(ii)
    input '请输入第'+ii_c+'个数值型数据:' to AA&ii_c
    AA0 = AA&ii_c
    jj=ii-1
    jj_c=transform(jj)
    do while .t.    &&为什么用 do while AA0 < AA&jj_c 出现不是预知的逻辑错误呢?
   if AA0 < AA&jj_c   && transform(0) 就是返回 '0'
      jj1_c=transform(jj+1)
      AA&jj1_c = AA&jj_c
      jj=jj-1
      jj_c=transform(jj)
      k=k+1
   else
      exit
   endif
    enddo
    jj1_c=transform(jj+1)
    AA&jj1_c = AA0
  endfor

  for ii=1 to 5
    ii_c=transform(ii)
    ? 'AA'+ii_c+':'+transform(AA&ii_c)
  ENDFOR
 ?k
 
 
 * 第二段代码:
k=0
input '请输入第1个数值型数据:' to AA1
  for ii=2 to 5    && 10个数组排序,n=10
    ii_c=transform(ii)
    input '请输入第'+ii_c+'个数值型数据:' to AA&ii_c
    AA0 = AA&ii_c
    jj=ii-1
    jj_c=transform(jj)
    do while AA0 < AA&jj_c  AND jj>0  &&为什么 do while AA0 < AA&jj_c 出现逻辑错误呢?  transform(0) 就是返回 '0'
       jj1_c = transform(jj+1)
       AA&jj1_c = AA&jj_c
       jj = jj-1
       jj_c = transform(jj)
       k=k+1
    enddo
    jj1_c=transform(jj+1)
    AA&jj1_c = AA0
  endfor
?k
  for ii=1 to 5
    ii_c=transform(ii)
    ? 'AA'+ii_c+':'+transform(AA&ii_c)
  ENDFOR
  
2018-06-07 11:36



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




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

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