2017-02-08 2 views
0

키보드의 입력 문자열에서 공백 문자와 함께 대문자와 소문자가 모두 나타나는 횟수를 계산하려고합니다.MIPS - 각 소문자, 대문자 및 공백 문자의 빈도

ASCII에서는 a-z가 97-122이고 A-Z는 65-90이라는 것을 알고 있습니다. 어셈블리와 함께이 알고리즘을 구현하는 방법을 잘 모르겠다. 개념이 매우 혼란 스럽다. 이 문제를 접근하는 방법 인 경우

// Uppercase 
array[0] = -65 
if (character read from string > 64) { 
    if (character read from string < 91) { 
    increment array[i] based on character 
    } 
} 
// Print out integers stored in array (the frequency) 

나는 확실하지 않다 :

내 psuedocode이의 라인을 따라 무언가이다.

.data 
prompt:  .asciiz "Please enter a string: \n" 
userString: .space 104 
occLow:  .space 104 
occUpp:  .space 104 
newLine: .asciiz "\n" 

####################### 
# t0 = string 
# t1 = char being looked at 
# t2 = counter 
# s0 = array lower (occLow) 
# s1 = array upper (occUpp) 
####################### 

    .text 
main: li $v0, 4 
     la $a0, prompt  # Prompts the user for string 
     syscall 

     li $v0, 8   # Save string to $a0 
     la $a0, userString 
     move $t0, $a0   # Move $a0 to $t0 
     syscall 

test: lb $t1, 0($t0)   # Load each individual character 
     beqz $t1, end   # If it is null, end program 
     addi $t0, $t0, 1   # Next char 

     beq $t1, 32, space  # If the character is a space 
     blt $t1, 91, upper  # Uppercase character, 90 = 'Z' 
     bgt $t1, 96, lower  # Lowercase character 
     b test 


upper1: bgt $t1, 64, upper2 # 65 = 'A' 
     b test 
upper2: # UPPERCASE ADDITIONS HERE 
     # la $s0, occUpp 
     # add $t0, $t0, 4 
     # lw $t1, 0($s0) 
     # addi $t2, 1 
     # sw $t1, 
+0

의사 코드가 너무 유사합니다. 1)'goto' 2) 단일 할당 (예 :'y = 2 * x + z' 없음) 만 사용하여 C에서 작동중인 구현을 작성하십시오. –

답변

0
// Uppercase 
array[0] = -65 
if (character read from string > 64) { 
    if (character read from string < 91) { 
    increment array[i] based on character 
    } 
} 
// Print out integers stored in array (the frequency) 

일부 짜증나는 스타일 노트 :


왜> 64 < (91) 대문자를 쓴 65 90에? 실제로 대부분의 어셈블러는 ASCII 형식을 처리 할 수 ​​있으므로 대문자는 'A'에서 'Z'까지입니다.

의사 코드에서 본인의 원래 의도대로 유지하려고하므로 문자가 65에서 90 (포함)인지 확인하십시오.


character = next_char(); if (character < 'A') goto not_uppercase; if ('Z' < character) goto not_uppercase; // uppercase detected ... not_uppercase: // character is not uppercase ... 

그래서 당신은 문자를 기반으로 i 싶다 "증가 배열 [내가] 캐릭터를 기반으로". 캐릭터 란 무엇인가? 입력 값이 ASCII로 인코딩되었으므로 0에서 255 사이의 값을 가지므로 단일 문자는 8 비트 값입니다. 0-255 값은 배열을 인덱싱하기에 충분합니까? 256 요소 배열을 예약하면 실제로입니다. 통계를 계산할 필요가없는 코드를 확인하여 메모리 효율을 높일 수 있습니다. 예를 들어 32-127 값의 통계 만 계산하면 96 개의 카운터 배열 만 필요하고 인덱스는 (character-32)이됩니다. 소문자와 대문자를 함께 사용하려면 -32 ('a'-32 == 'A' < =>97-32 == 65)으로 대문자를 대문자로 입력하십시오.

하지만 256 개의 요소 배열을 사용하여 개별적으로 (인쇄 할 수없는 문자열의 내용까지도) 모두 계산 한 다음 원하는대로 대/소문자/공백/숫자 부분 만 선택/그룹화 할 수 있습니다.

그럼 의사는 다음과 같이 보일 수 있습니다 :

charCounters = array(256) { 0, 0, ... }; 
// ^^^ counters for each possible letter set to zero 
for_each(character in string) { 
    ++charCounters[character]; // count particular letter 
} 
// counters are now updated, displaying results 

// for example total count of uppercase 
uppercaseLettersTotalCount = 0; 
for (i = 'A' to 'Z') { 
    uppercaseLettersTotalCount += charCounters[i]; 
} 
display("Total uppercase letters: " + uppercaseLettersTotalCount); 

// number of 'A' letters, both upper and lowercase 
totalA = charCounters['A']; 
totalA += charCounters['a']; 
display("Total A/a letters: " + totalA); 

// ... etc 

당신이 짧은 문자열에서 개별 문자의 개수 (5-30 문자)를 표시하려면, 그것은 빠르고 메모리를 적게 될 것입니다 순진한 파괴적인 두 개의 내부 루프를 수행하고 char에 의해 char을 처리하고 문자열의 나머지 부분에서 같은 문자를 계산합니다.

for (string_index in [0, string_length - 1]) { 
    character = string[string_index]; 
    if (0 == character) continue; // was already counted 
    count = 1; 
    for (index2 in [string_index + 1, string_length - 1]) { 
     if (character != string[index2]) continue; // different char 
     ++count;    // same character found 
     string[index2] = 0; // mark as counted (destroys input string) 
    } 
    display("Character " + character + " found " + count + " many times.\n"); 
}