У меня есть шнурок statistics
. Мне нужно найти уникальные или неповторяющиеся символы a,c
. Я нашел решение. Но для этого нужно использовать три цикла for. Как мы можем найти простое решение, которое требует меньше времени.
List<String> list=[];
List<String> newList=[];
//Loop one
for(int i=0; i<name.length;i++){
list.add(name[i]);
}
print(list);
newList =list.toSet().toList();
//Loop two
for(int j=0;j<list.length;j++){
//Loop three
for(int k=j+1;k<list.length;k++){
if (list[j]==list[k]){
newList.remove(list[j]);
}
}
}
print(newList);
Ваш подход медленный, потому что вам нужно постоянно перебирать входную строку, чтобы определить, существует ли символ в другом месте строки. Если вы хотите, чтобы поиск был быстрым, вы должны использовать Map
или Set
.
Map
, который сопоставляет отдельные символы со счетом.Map
(или инициализируйте его счетчик равным 1, если он еще не присутствует в Map
).Map
и извлеките все символы, число которых равно 1.Этот подход будет O (n) WRT длины строки вместо вашего текущего подхода O (n ^ 3) (каждый из двух вложенных циклов вносит мультипликативный коэффициент n, а newList.remove()
добавляет еще один скрытый коэффициент n).
void main() {
var s = 'statistics';
var charCodeCounts = <String, int>{};
for (var i = 0; i < s.length; i += 1) {
charCodeCounts[s[i]] = (charCodeCounts[s[i]] ?? 0) + 1;
}
var uniqueCharCodes = <String>[
for (var entry in charCodeCounts.entries)
if (entry.value == 1) entry.key,
];
print(uniqueCharCodes); // Prints: [a, c]
}
Вы можете запустить только один цикл for с listAsASet и проверить, совпадает ли первый индекс символа с последним индексом того же символа.
См. пример ниже:
void main() {
String sampleString = 'asdasfgalfnvcanalsdkalkcmaslksavnajskhauroewu982138954fndslkjanca135faca31asdcgdsa';
var sampleStringAsList = sampleString.split('');
var sampleStringAsSet = sampleStringAsList.toSet();
var uniqueCharactersList = [];
for(var character in sampleStringAsSet){
if (sampleStringAsList.indexOf(character) == sampleStringAsList.lastIndexOf(character)){
uniqueCharactersList.add(character);
}
}
print(uniqueCharactersList);
}
Я не уверен, что метод split запускает дополнительный цикл for в фоновом режиме.
Вы также можете использовать методы объекта String, чтобы сократить свой код, например, метод indexOf находит первое совпадение строки, которую вы ему передаете, тогда тот же indexOf имеет возможность найти индекс, где бы вы ни хотели, чтобы он начинался в строка, так что вы можете сначала найдите слово «е» в «Нью-Йорк», а затем выполните еще один поиск по первому совпадению индекса «е», тогда, если результат равен -1, это потому, что он уникален.
const string = 'New York';
final firstIndex = string.indexOf('e'); // prints the index of 'e'
final unique = string.indexOf('e', firstIndex); // prints if 'e' appears again after first match, if it prints -1 is unique, if gives an index is not unique
Дополнительная информация: https://api.dart.dev/stable/2.16.1/dart-core/String/indexOf.html