Home > Software design >  (dart) replaceAll method in a string in a loop (cypher)
(dart) replaceAll method in a string in a loop (cypher)

Time:08-16

I'm attempting to do CS50 courses in dart, so for week 2 substitution test i'm stuck with this:

    void main(List<String> args) {
  String alphabet = 'abcdefghijklmnopqrstuvwxyz';
  String cypher = 'qwertyuiopasdfghjklzxcvbnm';
  int n = alphabet.length;

  print('entertext:');
  String text = stdin.readLineSync(encoding: utf8)!;

  for (int i = 0; i < n; i  ) {
    text = text.replaceAll(alphabet[i], cypher[i]);
  }
  print(text);
}

Expected result: abcdef = qwerty

Actual result: jvmkmn

Any ideas why this is happening? I'm a total beginner by the way

CodePudding user response:

It is because you at first substitute the letter a with the letter q, but when n = 16, you will replace all the letter q with the letter j. This is why your a is turned into a j, and so forth...

Best of luck to you :)

CodePudding user response:

For the record, the (very direct and) safer approach would be:

void main(List<String> args) {
  String alphabet = 'abcdefghijklmnopqrstuvwxyz';
  String cypher = 'qwertyuiopasdfghjklzxcvbnm';

  assert(alphabet.length == cypher.length);
  
  // Pattern matching any character in `alphabet`.
  var re = RegExp('[${RegExp.escape(alphabet)}]');

  print('enter text:');
  String text = stdin.readLineSync(encoding: utf8)!;
  
  // Replace each character matched by `re` with the corresponding 
  // character in `cypher`.
  text = text.replaceAllMapped(re, (m) => cypher[alphabet.indexOf(m[0]!)]);
  print(text);
}

(This is not an efficient approach. It does a linear lookup in the alphabet for each character. A more efficient approach would either recognize that the alphabet is a contiguous range of character codes, and just do some arithmetic to find the position in the alphabet, or (if it wasn't a contiguous range) could build a more efficient lookup table for the alphabet first).

  • Related