【问题标题】:Bubble sort with variable number of inputs具有可变输入数量的冒泡排序
【发布时间】:2021-02-11 01:33:20
【问题描述】:

我正在为 Little Man Computer 开发一个冒泡排序程序,我希望它具有可变数量的输入(例如 500 个),之后程序将停止接受输入并将值从最小到最大排序。

请注意,在冒泡排序中应接受零作为数字。因此,如果输入是 3、5、6、0,那么它应该将它们排序为 0、3、5、6。

【问题讨论】:

  • 关于示例:程序如何知道在第三次输入之后还有另一个输入是预期的,而在第四次之后它不应该等待更多输入,而是产生排序输出?然后我建议第一个输入值应该表示之后将输入多少个值。这就是你想要的吗?
  • 是的,第一个输入值应该表示将接收或估算多少个值。我只是不知道那个会怎么样。我在考虑 INP 500,但我认为这不对。
  • 确实,这是不对的。 INP 在 LMC 中不接受任何参数。它将输入值加载到累加器中,因此后面应该跟STO size 之类的东西。然后将该值复制到一个计数器变量中,然后在循环中将其减小到零。如果您需要另一个循环,而不是再次从 size 复制到计数器中,...等等。
  • 你能给我看一个例子,看看我是否可以修改它吗?

标签: bubble-sort little-man-computer


【解决方案1】:

这个想法是为其余输入的长度保留第一个输入。通过这种方式,您可以知道何时采用了所有值。所以在你的例子中:

3 5 6 0

实际输入值必须是

4 3 5 6 0

...其中 4 告诉我们后面有 4 个数据值。

所以这意味着程序会以这样的方式开始:

     INP
     BRZ quit ; nothing to do
     STA size
     ; .... other code ....
quit HLT
size DAT 

然后代码需要使用这个size 来初始化一个计数器,并获取剩余的输入

        LDA size
        SUB one
loop    STA counter
        INP ; take the next input
        ; .... process this value ....
        LDA counter ; decrement the counter
        SUB one
        BRP loop ; while no underflow: repeat
        ; ... other processing on the collected input ...
quit    HLT
counter DAT

当您有多个(可能是嵌套的)循环时,例如冒泡排序,您必须管理多个计数器。

应用于冒泡排序

this answer 中,您将找到一个冒泡排序的实现,其中输入需要以 0 终止。在这里,我为您提供该解决方案的变体,其中 0 不再用作输入终止符,但第一个input 表示输入后面的值数组的长度。

请注意,这会使代码稍长一些,因此用于存储输入数组的剩余空间会变小:这里只有 25 个邮箱可供数组使用。在标准 LMC 上,永远不可能存储 500 个输入,因为总共只有 100 个邮箱,而代码占用了其中的一些邮箱。

在算法中(加载输入后),外循环需要迭代size-1次,内循环每次外循环迭代一次需要少迭代一次(这是冒泡排序的标准原理)。

#input: 10 4 3 2 1 0 9 8 5 6 7 
         LDA setfirst
         STA setcurr1
         INP
         BRZ zero ; nothing to do
         SUB one
         STA size ; actually one less
input    STA counter1
         INP
setcurr1 STA array
         LDA setcurr1
         ADD one
         STA setcurr1
         LDA counter1
         SUB one
         BRP input
         LDA size
         BRA dec
sort     STA counter1
         LDA getfirst 
         STA getcurr1
         STA getcurr2
         LDA setfirst
         STA setcurr2
         LDA cmpfirst
         STA cmpcurr
         LDA counter1
loop     STA counter2
         LDA getcurr1 
         ADD one
         STA getnext1
         STA getnext2
         LDA setcurr2
         ADD one
         STA setnext
getnext1 LDA array
cmpcurr  SUB array
         BRP inc
getcurr1 LDA array
         STA temp
getnext2 LDA array
setcurr2 STA array
         LDA temp
setnext  STA array
inc      LDA getnext1 
         STA getcurr1
         LDA setnext
         STA setcurr2
         LDA cmpcurr
         ADD one
         STA cmpcurr
         LDA counter2
         SUB one
         BRP loop
         LDA counter1
dec      SUB one
         BRP sort
         LDA size
output   STA counter1
getcurr2 LDA array
         OUT
         LDA getcurr2
         ADD one
         STA getcurr2
         LDA counter1
         SUB one
         BRP output
zero     HLT
one      DAT 1 
getfirst LDA array
setfirst STA array
cmpfirst SUB array
size     DAT
counter1 DAT
counter2 DAT
temp     DAT
array    DAT

<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.77/lmc.js"></script>

【讨论】:

  • 所以当我以 500 作为第一个要设置的数字运行您的代码时,由于空间不足,它会给出操作码 400 错误,对吗?
  • 是的,此代码不会验证此类溢出,因为这会占用更多空间。所以是的,当 STA 指令从 399 增加到 400 时,它只是遇到了无效的操作码,突然变成了非 STA 指令(3xx 是 STA,而 4xx 是未定义的操作码)。
  • 好吧,这就是我的想法,因为它确实如您所说的那样,并且是在您希望输入一定数量的地方进行输入的好代码。 e-LMC 允许像这样更大的内存,因此它可以与其他代码一起使用以取出零并使用选定的输入 500。感谢您的帮助,完成后我将在此处发布我的最终代码。跨度>
  • 这个项目还有一个要求,它应该对所需的输入量进行排序,然后对它们进行排序显示它们并重新开始。这段代码可以做到吗?
  • 那么无限循环?好吧,你知道BRA 做了什么,对吧? ;-)
【解决方案2】:
This is the final code and some basic information.

// Basic Outline
// 1) Initialize (may be empty)
// 2) Input Count
// 3) Handle Special Cases, GoTo 1 (will now be no special cases)
// 4) Input List
// 5) Sort the list (using Bubblesort)
// 6) Output List
// 7) GoTo 1
//
// Program uses an LMCe, same as an LMC except that it has an extra digit. 
//The number of memory cells is thus 1000 and the range of values is from 0 to 9999.
//
// Memory Map
//
// 0 – 79 the program
// 80-87 unused (may be used to test sorting in LMCs)
// 88-99 constants and variables
// 100 – 999 the list to be sorted.
//
// INITIALIZE (This section is blank)
//
// INPUT COUNT
//
000 IN 9001 // input count
001 STO 090 3090 // store count
//
// SPECIAL CASES (This section is now blank)
//
// INPUT LIST
//
002 LDA 096 5096 // STO
003 ADD 095 1095 // Determine first location
004 STO 011 3011 // Overwrite STO instruction for list
005 ADD 090 1090
006 STO 092 3092 // Store STO + LOC + Count to determine end
//
// INPUT LIST LOOP
007 LDA 011 5013 // Load manipulated instruction (using as counter)
008 SUB 092 2092 //
009 BRZ 016 7016 // If last count, go to END INPUT LIST
010 IN 9001 //
011 DAT 0 // manipulated instruction (store input in list)
012 LDA 011 5011
013 ADD 098 1098 // increment store instruction (to next list location)
014 STO 011 3011 // Update STO instruction
015 BR 007 6007 // GOTO INPUT LIST LOOP
//
// END INPUT LIST
//
// BUBBLESORT
// Note: the ‘to’ is inclusive.
//
// for I = 0 to count – 1 do (may not be inclusive)
// for j = count – 1 downto I + 1 do (may be inclusive)
// if A[j] < A[j-1]
// then exchange A[j] and A[j-1]
// end do
// end do
//
// If count < 2, then skip bubble sort
016 LDA 098 5098
017 SUB 090 2090 // 1 – count
018 BRP 061 8061 //. GO TO END I LOOP
//
// Initialize ‘I’ Counter
019 LDA 099 5099
020 STO 092 3092 // set I to zero (0)
//
// START I LOOP
//
021 LDA 090 5090
022 SUB 098 2098 // COUNT - 1
023 SUB 092 1092 // COUNT -1 – I
024 BRZ 061 7061 // if(I == count - 1) GOTO END I LOOP
//
// Initialize J
025 LDA 090 5090
026 SUB 098 2098
027 STO 093 3093 // J = Count – 1
//
// START J LOOP
//
028 LDA 092 5092 // I
029 SUB 093 2093 // I - J
030 BRP 057 8057 // If I == j, then GO END J LOOP
//
// Compare A[j] and A[j-1]
//
// Load A[j] into variable
031 LDA 097 5097 // load LDA instruction numeric code
032 ADD 095 1095 // set to LDA 500
033 ADD 093 1093 // set to LDA [500 + j] or A[j]
034 STO 039 3039 // reset instruction
035 SUB 098 2098 // set to LDA [500 + j – 1] or A[j-1]
036 STO 037 3037 // reset instruction
//
// Load and compare A[j] and A[j-1]
037 DAT 0 // load A[j-1] (instruction is manipulated)
038 STO 088 3088
039 DAT 0 // load A[j] (instruction is manipulated)
040 STO 089 3089
041 SUB 088 2088 // A[j] – A[j-1] (swap if not positive)
042 BRP 053 8053 // GOTO DECREMENT J
//
// swap the variables
//
// set up the STO variables
043 LDA 096 5096 // load STO instruction code
044 ADD 095 1095 // set to STO 500
045 ADD 093 1093 // set to STO [500 + j]
046 STO 052 3052 // reset instruction
047 SUB 098 2098 // set to STO [500 + j – 1]
048 STO 050 3050 // reset instruction
//
// do the swap (no need for a variable since they are already stored)
049 LDA 089 5089 // load A[j]
050 DAT 0 // Store in A[j-1] (instruction is manipulated)
051 LDA 088 5088 // load A[j-1]
052 DAT 0 // Store in A[j] (instruction is manipulated)
//
// DECREMENT J
//
053 LDA 093 5093
054 SUB 098 2098
055 STO 093 3093 // J = J – 1
056 BR 028 6028 // GOTO START J LOOP
//
// END J LOOP
//
// Increment I
057 LDA 092 5092
058 ADD 098 1098
059 STO 092 3092 // I = I + 1
060 BR 021 6021 // GOTO START I LOOP
//
// END I LOOP (End Bubblesort)
//
// OUTPUT COUNT
//
061 LDA 090 5090 // Count
062 OUT 9002
//
// OUTPUT LIST (now sorted)
// Initialize
063 LDA 097 5097
064 ADD 095 1095 // LDA + LOC
065 STO 071 3071 // set up instruction
066 ADD 090 1090 // LDA + LOC + Count
067 STO 092 3092 // store unreachable instruction
//
// OUTPUT LIST LOOP
068 LDA 071 5071 // load manipulated instruction (used as counter)
069 SUB 092 2092
070 BRZ 077 7077 // GOTO END OUTPUT LOOP
071 DAT 0 // manipulated output
072 OUT 9002
073 LDA 071 5071
074 ADD 098 1098
075 STO 071 3071 // increment manipulated instruction
076 BR 068 6028 // GOTO OUTPUT LIST LOOP
//
// END OUTPUT LOOP
077 BR 0 6000 // Branch to top of loop (embedded)
//
// End of program
078 HLT 0 // (Should never hit this instruction)
//
// Variables
088 DAT 0 // A[j-1] value (also used for swapping)
089 DAT 0 // A[j] value (also used for swapping)
//
090 DAT 0 // count variable (input and output)
091 DAT 0 // unused
092 DAT 0 // ‘I’ counter
093 DAT 0 // ‘j’ counter
//
// Constants
094 DAT 0 // unused
095 DAT 500 // initial list location
096 DAT 3000 // STO instruction
097 DAT 5000 // LDA instruction
098 DAT 1 // one (constant)
099 DAT 0 // zero (constant)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    相关资源
    最近更新 更多