R
语
言
调
试
案
例
:
寻
找
连
续
为
1
的
游
程
#
就
是
寻
找
一
个
向
量
中
连
续
为
1
的
位
置
,
例
如
1,0,1,1
则
返
回
3
findruns1<-function(x,k){
#x
是
输
入
的
向
量
,
2
是
连
续
为
2
个
n<-length(x)
runs<-vector(length=n)
count<-0
for(i in 1:(n-k+1)){
if(all(x[i:i+k-1]==1)){
count<-count+1
runs[count]<-i
}
}
if(count>0){
runs<-runs[1:count]
}
else runs<-NULL
return(runs)
}
findruns1(c(1,0,0,1,1,0,0,1,1,1),2)
[1] 3 4 7 8 9
显
然
,
出
错
了
调
试
方
法
一
:
手
动
,
在
程
序
中
添
加
多
个
print()
,
把
程
序
的
内
部
细
节
输
出
来
查
看
是
哪
里
出
的
问
题
。
function(x,k){
print(x)
#
输
出
x
print(k)
#
输
出
k
n<-length(x)
print(n)
#
输
出
n
runs<-vector(length=n)
count<-0
for(i in 1:(n-k+1)){
if(all(x[i:i+k-1]==1)){
count<-count+1
runs[count]<-i
print(runs)
#
输
出
循
环
的
每
一
步
}
}
if(count>0){
runs<-runs[1:count]
print(runs)
#
输
出
结
果
}
else runs<-NULL
return(runs)
}
findruns1(c(1,0,0,1,1,0,0,1,1,1),2)
[1] 1 0 0 1 1 0 0 1 1 1
#
正
确
[1] 2
#
正
确
[1] 10
#
正
确
[1] 3 0 0 0 0 0 0 0 0 0
#
出
错
!
!
[1] 3 4 0 0 0 0 0 0 0 0
[1] 3 4 7 0 0 0 0 0 0 0
[1] 3 4 7 8 0 0 0 0 0 0
[1] 3 4 7 8 9 0 0 0 0 0
[1] 3 4 7 8 9
[1] 3 4 7 8 9
可
以
看
出
,
从
把
实
参
带
入
形
参
,
到
建
立
长
度
等
于
x
长
度
的
向
量
,
都
是
正
确
的
。
错
误
开
始
于
循
环
的
第
一
步
。
因
此
我
们
应
该
去
检
查
循
环
语
句
,
不
难
发
现
,
问
题
出
在
all(x[i:i+k-1]==1)
中
,
我
们
没
有
把
i+k-1
扩
起
来
。
调
试
方
法
二
:
使
用
R
的
调
试
工
具
在
代
码
中
插
入
print()
显
然
比
较
繁
琐
,
特
别
是
程
序
较
长
的
时
候
,
使
用
R
的
调
试
工
具
会
更
便
捷
。
R
的
核
心
调
试
工
具
有
浏
览
器
构
成
,
它
可
以
让
你
逐
行
运
行
代
码
,
并
在
运
行
过
程
中
检
查
,
可
以
用
dubug(f)
或
browser()
打
开
这
个
浏
览
器
。
debug(f)
函
数
可
以
把
函
数
f()
设
置
成
调
试
状
态
,
意
味
着
每
次
调
用
f()
都
会
进
入
这
一
状
态
,
取
消
这
一
状
态
需
调
用
undebug(f)
。
在
2.10
版
本
之
后
,
可
以
用
debugonce()
代
替
(
检
查
漏
洞
一
次
)
。
基
本
调
试
命
令
在
进
入
dedbug
调
试
状
态
后
,
命
令
提
示
符
从
>
变
为
Browse[d]>(d
表
示
函
数
调
用
链
的
深
度
)
,
可
以
通
过
一
些
基
本
的
命
令
来
进
行
控
制
:
•
n(
表
示
next):
告
诉
R
执
行
下
一
行
代
码
,
并
且
执
行
完
后
马
上
暂
停
,
实
际
就
是
一
行
一
行
地
执
行
代
码
。
相
当
于
C
语
言
开
发
工
具
Turbo C
中
的
trace into
。
•
c(
表
示
continue):
表
示
会
执
行
若
干
条
语
句
。
若
当
前
处
在
循
环
中
,
这
一
步
会
执
行
完
整
个
循
环
,
若
当
前
处
在
函
数
内
但
又
不
再
循
环
中
,
则
会
执
行
完
当
前
函
数
。
相
当
于
C
语
言
开
发
工
具
Turbo C
中
的
step over
。
•
where:
输
出
一
份
栈
跟
踪
路
径
,
显
示
到
达
当
前
位
置
的
过
程
中
函
数
的
调
用
序
列
。
•
Q:
退
出
brower
,
返
回
R
的
主
交
互
模
式
。
•
任
意
R
命
令
:
即
使
在
调
试
状
态
browser
中
,
依
然
处
于
R
的
交
互
模
式
中
,
所
以
你
可
以
用
任
意
R
命
令
。
1.debugonce
()
debugonce(findruns1)
findruns1(c(1,0,0,1,1,0,0,1,1,1),2)
然
后
开
始
调
试
….
Browse[2]> x
[1] 1 0 0 1 1 0 0 1 1 1
Browse[2]>
debug at findruns1.R#2: n <- length(x)
Browse[2]>
debug at findruns1.R#3: runs <- vector(length = n)
Browse[2]> print(n)
[1] 10
Browse[2]>
debug at findruns1.R#4: count <- 0
Browse[2]>
debug at findruns1.R#5: for (i in 1:(n - k + 1)) {
if (all(x[i:i + k - 1] == 1)) {
count <- count + 1
runs[count] <- i
}
}
Browse[2]>
debug at findruns1.R#5: i
Browse[2]>
debug at findruns1.R#6: if (all(x[i:i + k - 1] == 1)) {
count <- count + 1
runs[count] <- i
}
Browse[2]> x[i:i+k-1]
#
出
错
[1] 0
Browse[2]> i:i+k-1
[1] 2
Browse[2]> i
[1] 1
Browse[2]> k
[1] 2
Browse[2]> Q
#
退
出
调
试
思
考
后
可
以
发
现
,
少
加
了
括
号
。
source("findruns.R")
> findruns(c(1,0,0,1,1,0,0,1,1,1),2)
[1] 4 8 9
正
确
。
下
面
这
个
案
例
是
用
递
归
算
法
排
序
qs<-function(x){
if(length(x)<=1)return(x)
pivot<-x[1]
therest<-x[-1]
sv1<-therest[therest<pivot]
sv2<-therest[therest>=pivot]
sv1<-qs(sv1)
sv2<-qs(sv2)
return(c(sv1,pivot,sv2))
}
a<-c(8,7,2,9,45,32)
source("qs.R")
> a<-c(8,7,2,9,45,32)
> qs(a)
[1]
2
7
8
9 32 45
结
果
是
正
确
的
,
但
运
算
过
程
是
比
较
让
人
费
解
的
。
本
人
要
说
明
的
是
,
调
试
工
具
不
仅
可
以
找
错
,
也
可
以
帮
助
理
解
程
序
的
运
行
过
程
。
debugonce(qs)
> qs(a)
debugging in: qs(a)
debug at qs.R#1: {
if (length(x) <= 1)
return(x)
pivot <- x[1]
therest <- x[-1]
sv1 <- therest[therest < pivot]
sv2 <- therest[therest >= pivot]
sv1 <- qs(sv1)
sv2 <- qs(sv2)
return(c(sv1, pivot, sv2))
}
Browse[2]>
debug at qs.R#2: if (length(x) <= 1) return(x)
Browse[2]>
debug at qs.R#2: NULL
Browse[2]> x
[1]
8
7
2
9 45 32
Browse[2]> length(x)
[1] 6
Browse[2]>
debug at qs.R#3: pivot <- x[1]
Browse[2]> pivot
Error: object 'pivot' not found
Browse[2]>
debug at qs.R#4: therest <- x[-1]
Browse[2]> pivot
[1] 8
Browse[2]>
debug at qs.R#5: sv1 <- therest[therest < pivot]
Browse[2]> therest
[1]
7
2
9 45 32
Browse[2]>
debug at qs.R#6: sv2 <- therest[therest >= pivot]
Browse[2]> sv1
[1] 7 2
Browse[2]>
debug at qs.R#7: sv1 <- qs(sv1)
Browse[2]> sv2
[1]
9 45 32
Browse[2]>
debug at qs.R#8: sv2 <- qs(sv2)
Browse[2]> sv1
[1] 2 7
Browse[2]>
debug at qs.R#9: return(c(sv1, pivot, sv2))
Browse[2]> sv2
[1]
9 32 45
Browse[2]>
[1]
2
7
8
9 32 45
看
到
每
一
步
的
结
果
,
对
程
序
的
理
解
必
然
会
更
深
刻
。
2.
browser()
开
启
调
试
:
在
R
源
文
件
中
的
指
定
位
置
插
入
函
数
browser()
,
保
存
源
文
件
,
运
行
源
程
序
,
程
序
一
旦
运
行
到
browser()
处
,
将
会
自
动
进
入
debug
状
态
。
取
消
调
试
:
但
当
用
户
完
成
调
试
后
,
需
要
手
动
删
除
源
文
件
中
的
browser()
函
数
,
否
则
每
次
运
行
到
browser()
位
置
都
会
进
入
debug
状
态
。
1.
countsum <- function(count)
2.
{
3.
sum <- 0
4.
for (i in 1:count)
5.
{
6.
sum <- sum + i
7.
}
8.
browser()
9.
return (sum)
10.
}
11.
results <- countsum(100)
12.
print(results)
调
试
方
式
同
debugonce()
3.
debug()
针
对
单
个
函
数
的
调
试
方
式
开
启
调
试
:
执
行
命
令
debug(fun)
fun
指
函
数
名
,
这
样
每
次
调
用
函
数
fun()
都
会
进
入
调
试
状
态
。
取
消
调
试
:
执
行
命
令
undebug(fun)
再
次
调
用
函
数
fun()
将
不
会
进
入
调
试
状
态
。
debug()
和
debugonce()
的
区
别
在
于
:
debugonce()
只
会
在
设
置
之
后
的
第
一
次
调
用
时
进
入
调
试
状
态
且
只
只
进
入
一
次
,
而
debug()
可
以
进
入
无
限
多
次
直
到
通
过
undebug()
取
消
调
试
。