Задачи, сгруппированные по методам решения. Использование дополнительного массива "флажков"
Для решения некоторых задач на одномерные массивы часто бывает необходимо каким-либо образом отметить элементы, удовлетворяющие условию. Для этого резервируют дополнительный массив Flag, элементы которого заполняют единицами, если соответствующие элементы исходного массива удовлетворяет условию.
Если условий несколько, то "флажки" принимают разное значение (например: "1" и "-1" и др.). Рассмотрим данный прием на практике.
Задача 1: Написать программу для поиска всех простых чисел (до числа N).
Дополнительные сведения: Рассмотрим алгоритм поиска простых чисел на диапазоне от 1 до N методом "Решето Эратосфена". Проиллюстрируем этот метод:
- 1 шаг: берем "2", отмечаем серым цветом. Вычеркиваем все числа, кратные двум.
- 2 шаг: берем следующее за "2" невычеркнутое число ("3"), отмечаем серым цветом. Вычеркиваем все числа, кратные трем и т.д.
-
В "решете" остались числа, отмеченные серым цветом. Это простые числа.
Идея решения:
-
Заполняем одномерный массив А подряд идущими числами до N (например: N=22) включительно (таблица ниже):
-
Заполняем элементы массива Flag флажками-единицами, если соответствующие элементы массива А кратны "2" (рис. 6.2):
-
Затем заполняем элементы массива Flag флажками-единицами, если соответствующие элементы массива А кратны "3" (рис. 6.3):
- и т.д.
-
В "решете" (массиве А) остались числа, отмеченные серым цветом (рис. 6.4):
Для сокращения количества шагов достаточно перебирать элементы массива А до половины (т.к. максимальный делитель n - это n/2).
Решение задачи на Бейсике:
input "n="; n dim a(n), flag(n) for i=1 to n a(i)=i next for i = 2 to n/2 if flag(i)=0 then for j=i+1 to n if a(j) mod a(i)=0 then flag(j)=1 next j end if next i for i=1 to n if flag(i)=0 then print a(i); next
Решение задачи на Паскале:
Program pr; Var a,flag:array [1..100] of integer; I,j,n:integer; begin writeln ('n='); readln (n); for i:=1 to n do a[i]:=i; for i:=2 to n div 2 do if flag[i]=0 then for j:=i+1 to n do if (a[j] mod a[i]=0) then flag[j]:=1; for i:=1 to n do if flag[i]=0 then writeln (a[i]); end.
Тест:
Задача 2: В одномерном массиве, заполненном целыми числами подсчитать число различных элементов.
Идея решения: сравнивая очередной элемент массива А с остальными элементами, заполняем единицей соответствующий повторяющемуся элементу элемент массива Flag. Количество нулевых элементов в массиве Flag и будет равно количеству различных элементов массива А.
Решение задачи На Бейсике:
input "количество чисел"; n dim a(n), flag(n) for i = 1 to n input "введите число"; a(i) next for i = 1 to n - 1 if flag(i) = 0 then for j = i + 1 to n if a(i)=a(j) then flag(j)=1 next end if next for i = 1 to n if flag(i)=0 then k = k+1 next print "k="; k
Решение задачи на Паскале:
Program pr; var a,flag: array [1..100] of integer; i,j,n,k: integer; begin writeln ('количество чисел'); readln (n); for i:= 1 to n do begin writeln ('введите число'); readln (a[i]); end; {==========================} for i:=1 to n-1 do if flag[i]=0 then for j:=i+1 to n do if a[i]=a[j] then flag[j]:=1; for i:=1 to n do if flag[i]=0 then k:=k+1; writeln ('k=', k); end.
Тест:
Задача 3: Вывести элемент, встречающийся в одномерном массиве чаще других.
Идея решения: При сравнении элементов массива А находим повторяющиеся элементы. Массив Flag заполняем количеством повторений элемента массива А. Затем, применив типовой алгоритм ПОИСКА МАКСИМАЛЬНОГО ЭЛЕМЕТА МАССИВА находим позицию элемента массива А, встречающегося чаще других.
Решение задачи на Бейсике:
input "количество чисел";n dim a(n), flag(n) for i = 1 to n input "введите число"; a(i) next for i = 1 to n - 1 if flag(i) = 0 then for j = i + 1 to n if a(i) = a(j) then k = k + 1: flag(j) = k next k = 0 end if next for i = 1 to n if flag(i) > max then max = flag(i): b = i next print "чаще встречается "; a(b);
Решение задачи на Паскале:
var a,flag: array [1..100] of integer; i,j,n,k,max,b: integer; begin writeln ('количество чисел'); readln (n); for i:= 1 to n do begin writeln ('введите число'); readln (a[i]); end; {===================} k:=0; for i:=1 to n-1 do if flag[i]= 0 then for j:=i+1 to n do begin if a[i]= a[j] then begin k:= k+1; flag[j]:=k; end; k:=0; end; max:=flag[1]; for i:=1 to n do if flag[i]>max then begin max:=flag[i]; b:=i; end; writeln ('чаще встречается ', a[b]); end.
Тест:
Ключевые термины
Краткие итоги
Для решения некоторых задач на одномерные массивы часто бывает необходимо каким-либо образом отметить элементы, удовлетворяющие условию. Для этого резервируют дополнительный массив флажков, элементы которого заполняют единицами, если соответствующие элементы исходного массива удовлетворяет условию.
В алгоритме "Решето Эратосфена" флажками отмечаются элементы, которые необходимо исключить из дальнейшего рассмотрения ("вычеркнуть").
При необходимости флажки могут принимать не только единичные значения - они могут "указывать" на разнообразные состояния элементов рассматриваемого массива.
Набор для практики
Вопросы.
- Продолжите фразу: "Для того, чтобы отметить элементы, удовлетворяющие условию, используют…".
- В чем заключается алгоритм поиска простых чисел на диапазоне от 1 до N методом "Решето Эратосфена"?
Упражнения.
- В одномерном массиве, заполненном целыми числами подсчитать количество повторяющихся элементов.
- Ввести предложение, разобрать его на слова, поместив каждое слово в ячейку массива. Подсчитать, сколько слов в предложении имеют одинаковое количество букв.