Вот быстрый 100% скрипт bash, который сделает эту работу:
a=()
while read _ n; do
[[ -n $n ]] && ((++a[n]))
done < datafile.txt
c=0
for i in ${!a[@]}; do
echo "$((c+=a[i])) $i"
done
Если вам нужен скрипт, который вы можете вызвать из командной строки:
#!/bin/bash
a=()
while read _ n; do
[[ -n $n ]] && ((++a[n]))
done < "$1"
c=0
for i in ${!a[@]}; do
echo "$((c+=a[i])) $i"
done
Или, если вы предпочитаете однострочку, чтобы произвести впечатление на вашу бабушку:
a=(); while read _ n; do [[ -n $n ]] && ((++a[n])); done < datafile.txt; c=0; for i in ${!a[@]}; do echo "$((c+=a[i])) $i"; done
Он работает примерно за 2-3 секунды на двухъядерном процессоре Pentium с частотой 2,6 ГГц в файле с 100000 строк.
редактировать
Пояснения:
Первый цикл:
- Мы инициализируем,
aчтобы быть пустым массивом:a=()
- Мы читаем файл
datafile.txtпострочно. В каждой строке два поля, только второе добавляется в имена переменныхn
- Если
nне пусто (это тест, [[ -n $n ]]мы увеличиваем значение nключа -th массива a; это то, что ((++a[n]))делает строка . ((...))Это арифметический контекст bash.
- После прочтения всех файлов у нас есть массив
a, и kполе -th - это количество автономных систем, степень которых равна k.
Тогда второй цикл:
- Перед циклом переменная
cустанавливается в 0.
for i in ${!a[@]}; doбудет перебирать все ключи массива a.
$((c+=a[i]))добавит значение a[i]к cи расширит это значение. Это значение echoредактируется с iдобавлением значения ключа .
Надеюсь это поможет!