我读过一个编程问题,然后为其编写了代码。但我认为我的算法不能正常工作,所以我编写了另一段代码,它不是最优的,但我认为是正确的。
现在我有大约 100 个输入和输出数据集,我想将此输入提供给两个 C++ 程序并比较输出。如果输出存在差异,我会找出我的代码是否不正确。
我的问题是测试用例太多(大约100个)并且输出是大文本文件,我无法自己检查它们。我想知道如何使用 bash 函数和命令来做到这一点?
我的输入文本文件是input1.txt
、input2.txt
等。我的输出文本文件与输入类似。我的程序是用 C++ 编写的。
答案1
比较文本文件的最佳方法是使用diff
命令:
diff output1.txt output1.txt
对于质量比较,您可以diff
循环调用:
for x in input*.txt; do
slow-program <"$x" >"$x.out-slow"
fast-program <"$x" >"$x.out-fast"
diff "$x.out-slow" "$x.out-fast"
done
如果上面的代码片段产生任何输出,则您的快速程序有问题。在bash/ksh/zsh中,不需要将中间文件存储在磁盘上。然而,这不一定是一件好事,因为在闲暇时检查不同的输出可能很有用。
for x in input*.txt; do
diff <(slow-program <"$x") <(fast-program <"$x")
done
将输入和输出放在单独的目录中并执行递归比较可能会更方便。
for x in inputs/*; do slow-program <"$x" >"slow/${x##*/}"; done
for x in inputs/*; do fast-program <"$x" >"fast/${x##*/}"; done
diff -ru slow fast
我的建议是编写一个运行测试并执行比较(在单独的目标中)的 makefile。 (在我放置 8 个空格的地方使用制表符。)
all_test_inputs = $(wildcard input*.txt) # relies on GNU make
%.out-slow: %.txt slow-program
./slow-program <$< >[email protected]
mv [email protected] $@
%.out-fast: %.txt fast-program
./fast-program <$< >[email protected]
mv [email protected] $@
%.diff: %.out-slow %.out-fast
-diff $*.out-slow $*.out-fast >[email protected]
mv [email protected] $@
# Test that all diff files are empty
test: $(all_test_inputs:%.txt=%.diff)
for x in $^; do ! test -s "$x"; done
.PHONY: test
运行make test
处理所有输入文件(仅针对输入文件或自上次以来发生更改的程序)并比较结果。当且仅当所有测试都正确运行并且两个程序的输出在每种情况下都相同时,该命令才会成功。
答案2
假设您将程序编译为prog1
和prog2
,并且它们在 上生成输出stdout
,您可以执行以下操作:
#! /bin/bash
for input in input*.txt ; do
./prog1 $input > $input.out1
./prog2 $input > $input.out2
if cmp $input.out1 $input.out2 > /dev/null ; then
echo Programs disagreed on $input
else
echo Programs agreed on $input
fi
done
这会逐字节比较输出文件。您也可以用来diff
进行比较。
所有运行的输出将位于名为inputX.txt.out1
或 的文件中.out2
,因此您可以检查它们不匹配的情况。