Array  break  case  catch  const  continue  default  Date  do Error  else  Function  false  finally  for

function  if  in  instanceof  Infinity  Math  NaN  Number  new  null  Object  Promise  prototype  RegExp

return  String  switch  this  then  throw  try  true  undefined  var  with  while
	
alert(s)
appendChild(tagName)
fillRect()
pow(base, n)
sin(radians)
cos(radians)
random()
isNaN()
test()
sqrt(n)
prompt(s)
parseInt(s) parseFloat(s)
floor(f) 
ceil(f)
charAt(n)
indexOf(substring, offset)
substring(start, end)
replace(pattern, replacement)
toLowerCase(s)
toUpperCase(s)
abs(n)
splice(start, length, newItem1, newItem2, ...)
split(pattern, limit)
toString()
createElement(tagName)

getElementById(id)

getContext(contextType)

removeChild(domElement)

strokeText(text, x, y)

fillText(text, x, y)

measureText(text)

setItem(key, value)

join(delimeter)

round(floatNumber)
	

Массивы

В задачах могут встречаться упоминания "одномерных", "двумерных", "n-мерных" массивов. Это связано с тем, что задачи писались для решения их на языке Pascal, в котором массив может быть двумерным "на уровне языка". Поэтому не стоит зацикливаться на этих прилагательных.

Первая задача

Найти сумму элементов, больших данного числа А (А вводится с клавиатуры).

function sumElementsGreatThanA() {
	"use strict"
	var array = [0,5,8,98,256,56,1,-265,0,696], //Абсолютно наобум придумал себе массив
		A = parseFloat(readln("Введите А")), i = array.length, sum = 0;
	if (isNaN(A)) {
		writeln("A должно быть числом!");
		return;
	}
	while (i--) { //цикл будет выполняться, пока i != 0
		if (array[i] > A) {
			sum += array[i];//Так короче, чем sum = sum + array[i];
		}
	}
	writeln("S = " + sum);
}

Если вы разобрались с предыдущими примерами, этот вряд ли станет для вас непонятным.

Я объявил массив с именем array, поместил туда какие-то произвольные числа. Количество элементов в массиве можно получить используя свойство переменной (объекта типа) Array length. Элементы массива нумеруются от 0 до (array.length - 1).

Так как для решения задачи не имеет значения, проходить массив от начала к хвосту или наоборот, я иду от конца к началу. Это позволяет проверять, прекращать ли цикл, сравнивая i с нулем. Я уже упоминал рассматривая циклы о поведении операции i++, i-- ведет себя также. Если вы пропустили этот фрагмент читая про циклы, я приведу его еще раз:

function plusPlusBehavior() {
	var a, d, b = 1, c = 1;
	a = b++;//Записали в a значение b, после чего увеличили b на единицу 
	d = ++c;//увеличили c на единицу, после чего записали в d значение c
	writeln('a = ' + a + ', b = ' + b + ', c = ' + c + ', d = ' + d);
}

Таким образом, в коде примере sumElementsGreatThanA, в цикле я сначала сравниваю i c нулем, потом уменьшаю его на единицу и лишь потом выполняется тело цикла. Благодаря этому на первой итерации в условии

if (array[i] > A)

i равно уже не array.length, а array.length - 1. Таким образом, я корректно прохожу по всем индексам массива, не выходя никогда за его пределы.

В условном операторе я сравниваю i-тый элемент массива с A после чего, если он больше чем A прибавляю его к сумме. В конце вывожу сумму. Все просто и прозаично.

Вторая задача

Ввести координаты ферзя и коня и определить: если конь ходит первым, то бьёт ли он ферзя.

Сначала напишу программку, а потом разберем ее, читайте также комментарии в коде. Потом я немного усложню (или скорее упрощу, так как станет меньше кода) реализацию.


function chessStep() {
	var chessBoard = [],//Это будет шахматная доска
	knightCoordinates = readln('Введите позицию коня, например e2 или h8'), 
	queenCoordinates  = readln('Введите позицию ферзя, например a1 или f5'),
	i, j, //для цикла и для преобразования координат фигур из "шахматного" формата в цифровой
	newI, newJ, //для хранения новых координат коня
	errorMessage = "Введите позиции фигур как принято в шахматах, например e2 или  e4",
	successMessage = "Конь съел ферзя!",
	failMessage    = "Конь не волк, в поле убежал",
	letters = 'abcdefgh'; //буквы, используемые на доске для обозначения клеток
	if (knightCoordinates.length != 2 || queenCoordinates.length != 2) {
		writeln(errorMessage);
		return;
	}
	//создаем в оперативной памяти шахматную доску )
	for (i = 0; i < 8; i++) { //Чтобы можно было обращаться например  chessBoard[0][1]
		chessBoard.push( [] ); //сделаем каждый элемент массива пустым массивом
		for (j = 0; j < 8; j++) {
			chessBoard[i].push(''); //Забиваю пустыми строками


		}
	}
	//Установим ферзя
	queenCoordinates = queenCoordinates.toLowerCase();
	i = letters.indexOf( queenCoordinates.charAt(0) );
	j = parseInt(queenCoordinates.charAt(1), 10) - 1;
	if (i < 0 || isNaN(j) || j < 0 || j > 7) {//координаты фигур по вертикали и горизонтали должны быть в пределах [0-7]
		writeln(errorMessage);
		return;
	}
	chessBoard[i][j] = 'Q';//Записали в клетку, что там стоит ферзь. Цвет фигур в задаче необязательно учитывать
	//Установим коня
	i = letters.indexOf( knightCoordinates.charAt(0) );
	j = parseInt(knightCoordinates.charAt(1), 10) - 1;
	if (i < 0 || isNaN(j) || j < 0 || j > 7) {//координаты фигур по вертикали и горизонтали должны быть в пределах [0-7]
		writeln(errorMessage);
		return;
	}
	//И проверяем все возможные позиции коня, "сверху" и по часовой стрелке.
	newI = i + 1;
	newJ = j + 2;
	if (newI < 8 && newJ < 8) {//не вышли ли за пределы доски?
		if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
			writeln(successMessage);
			return;
		}
	}
	newI = i + 2;
	newJ = j + 1;
	if (newI < 8 && newJ < 8) {//не вышли ли за пределы доски?
		if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
			writeln(successMessage);
			return;
		}
	}
	newI = i + 2;
	newJ = j - 1;
	if (newI < 8 && newJ > -1) {//не вышли ли за пределы доски?
		if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
			writeln(successMessage);
			return;
		}
	}
	newI = i + 1;
	newJ = j - 2;
	if (newI < 8 && newJ > -1) {//не вышли ли за пределы доски?
		if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
			writeln(successMessage);
			return;
		}
	}
	newI = i - 1;
	newJ = j - 2;
	if (newI > -1 && newJ > -1) {//не вышли ли за пределы доски?
		if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
			writeln(successMessage);
			return;
		}
	}
	newI = i - 2;
	newJ = j - 1;
	if (newI > -1 && newJ > -1) {//не вышли ли за пределы доски?
		if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
			writeln(successMessage);
			return;
		}
	}
	newI = i - 2;
	newJ = j + 1;
	if (newI > -1 && newJ < 8) {//не вышли ли за пределы доски?
		if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
			writeln(successMessage);
			return;
		}
	}
	newI = i - 1;
	newJ = j + 2;
	if (newI > -1 && newJ < 8) {//не вышли ли за пределы доски?
		if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
			writeln(successMessage);
			return;
		}
	}
	writeln(failMessage);
}

От ключевого слова var до первой точки с запятой вам должно быть уже все понятно, объявляю переменные, в комментариях рядом пишу, зачем они нужны. В переменной chessBoard буду хранить информацию о позициях фигур на доске, но для начала я определяю её (инициализую её) пустым массивом. К требуемой мне в работе инициализации этого массива я приступаю после того, как убеждаюсь что позиции коня и ферзя заданы строками, состоящими из двух символов. В цикле я добавляю в наш пустой массив восемь массивов, состоящих из восьми элементов - пустых строк. Это позволит записывать в эти элементы информацию о том, какая фигура стоит на данной позиции, например я мог бы записать туда словосочетание "белый конь". Правда, в реальной программе я скорее всего присвоил каждой фигуре уникальный номер (с учетом цвета) и записывал бы его.

После того, как "доска"готова, я устанавливаю на ней ферзя. Программа ожидает, что пользователь будет вводить позиции фигур так, как это принято записывать в шахматах, например "a2". Но ничто не мешает ввести пользователю вместо "h5" "H5", поэтому я привожу введенную строку к нижнему регистру (то есть все прописные буквы заменяю строчными), воспользовавшись для этого методом String toLowerCase. В полученном значении я получаю первый (точнее нулевой) символ методом charAt и смотрю, есть ли такой символ в строке letters, содержащей допустимые для ввода буквы. Второй символ переменной queenCoordinates ожидаем как число, поэтому я использую функцию parseInt.

Таким образом, я преобразовал строку из queenCoordinates в два целых значения и поместил их в переменные i и j. Значения этих переменных должны быть от нуля до семи включительно (элементы массива нумеруются с нуля), и я проверяю это с помощью условного оператора if, выводя в случае несоответствия диапазону строку, хранящуюся в переменной errorMessage, после чего завершаю выполнение программы с помощью служебного слова return. Если значения укладываются в нужный мне диапазон, продолжаем выполнение программы, записываем в соответствующую клетку доски значение 'Q'. Это будет нам говорить о том, что на данной клетке стоит ферзь.

Далее, абсолютно аналогично тому, как это делалось для ферзя, получаем координаты коня. Если они также укладываются в диапазон от нуля до семи, начинаю последоватенльно вычислять все возможные ходы конем по часовой стрелке. Если после одного из вычислений в ячейке массива newJ, newI записан символ 'Q', можно завершить вычисления - ферзь "съеден". Иначе - ферзь не может быть взят конем, вывожу соответствующее сообщение и на этом все.

Программка работает, однако, здесь у меня много повторяющегося кода. Преобразование позиции фигур в координаты массива chessBoard просится в отдельную функцию, с восемью очень похожими друг на друга участками кода проверки не вышел ли конь за пределы доски и не съел ли ферзя тоже надо что-то делать.

Я введу вспомогательный массив steps и перепишу свое решение так:


function chessStep() {
	"use strict"
	var chessBoard = [],//Это будет шахматная доска
	knightCoordinates = readln('Введите позицию коня, например e2 или h8'), 
	queenCoordinates  = readln('Введите позицию ферзя, например a1 или f5'),
	i, j, m, n,  //для цикла и для преобразования координат фигур из "шахматного" формата в цифровой
	newI, newJ, //для хранения новых координат коня
	errorMessage = "Введите позиции фигур как принято в шахматах, например e2 или  e4",
	successMessage = "Конь съел ферзя!",
	failMessage    = "Конь не волк, в поле убежал",
	letters = 'abcdefgh', //буквы, используемые на доске для обозначения клеток
	steps = [-2, -1, 1, 2]; //буду использовать для проверки "ходов конем"
	if (knightCoordinates.length != 2 || queenCoordinates.length != 2) {
		writeln(errorMessage);
		return;
	}
	//создаем в оперативной памяти шахматную доску )
	for (i = 0; i < 8; i++) { //Чтобы можно было обращаться например  chessBoard[0][1]
		chessBoard.push( [] ); //сделаем каждый элемент массива пустым массивом
		for (j = 0; j < 8; j++) {
			chessBoard[i].push(''); //Забиваю пустыми строками
		}
	}
	function setFigure(figureCoordinates, letter) {
		figureCoordinates = figureCoordinates.toLowerCase();
		i = letters.indexOf( figureCoordinates.charAt(0) );
		j = parseInt(figureCoordinates.charAt(1), 10) - 1;
		if (i < 0 || isNaN(j) || j < 0 || j > 7) {//координаты фигур по вертикали и горизонтали должны быть в пределах [0-7]
			writeln(errorMessage);
			return false;
		}
		chessBoard[i][j] = letter;//Записали в клетку, что там стоит ферзь. Цвет фигур в задаче необязательно учитывать
		return true;
	}
	//Установим ферзя
	if ( !setFigure(queenCoordinates, 'Q') ) { //не удалось установить фигуру
		return; //выходим
	}
	//Установим коня
	if ( !setFigure(knightCoordinates, 'K') ) { //не удалось установить фигуру
		return; //выходим
	}
	//И проверяем все возможные позиции коня, "сверху" и по часовой стрелке.
	for (m = 0; m < steps.length; m++) {
		newI = steps[m];  //сюда пока что поместим "приращение"
		for (n = 0; n < steps.length; n++) {
			newJ = steps[n];  //сюда пока что поместим "приращение"
			if ( Math.abs(newI) == Math.abs(newJ) ) { //конь ходит буквой 'Г', значит приращения не могут быть равны
				continue;
			}
			//прибавим приращения к позиции коня
			newI = i + newI;
			newJ = j + newJ;
			if (newI > -1 && newJ < 8 && newI < 8 && newJ > -1) {//не вышли ли за пределы доски?
				if (chessBoard[newI][newJ] == 'Q') {//Если там стоит ферзь
					writeln(successMessage);
					return;
				}
			}
			
		}
	}
	writeln(failMessage);
}

Добавленный цикл по элементам массива steps делает всю ту же работу, которую раньше выполняли восемь блоков if. Я поместил один из таких блоков внутрь вложенного цикла и сделал проверку диапазона значений newJ, newI более универсальной. В остальном код этого цикла достаточно прост для понимания, вопросов быть не должно.

О функции setFigure. Так как она определена внутри функции chessStep, это дает возможность использовать все переменные, определенные внутри chessStep. Вам может показаться, что я противоречу своему же совету всюду использовать слово var. Но это не так, ведь я не определяю внутри setFigure ни одной новой переменной.

Однако я еще вернусь к этой функции, когда буду решать пример по теме "Подпрограммы".

Перехожу к третьей подзадаче

Удаление элементов

Задание: удалить строку с номером k и столбец с номером m.

Очевидно, речь идет о двумерном массиве, таком как наша шахматная доска. Чтобы было визуально видно, что мы действительно удалим строку и столбец, добавим функции вывода элементов массива на экран, а сами элементы на этот раз заполним не пустыми строками

function removeRowAndColumnExample() {
	var array = [], i, j, 
		k, m,
		ARRAY_SIZE = 8; //По привычке оставшейся от прошлого примера взял размерность 8 на 8
	//заполним массив случайными цифрами от 0 до 9
	for (i = 0; i < ARRAY_SIZE; i++) {
		array.push([]);
		for (j = 0; j < ARRAY_SIZE; j++) {
			m = String( Math.random() );
			m = m.charAt(3) ? m.charAt(3) : '0'; //Почему именно третий? На самом деле от фонаря, мне ведь не важно что конкретно будет в массиве
			array[i].push(m);
		}
	}
	function printArray() {
		var i, j, s = "", L = array.length; //чтобы не переписывать неожиданно значения i j во внешней функции
		for (i = 0; i < L; i++) {
			for (j = 0; j < array[i].length; j++) {
				s += array[i][j] + ' ';
			}
			s += "\n";
		}
		writeln(s);
	}
	k = parseInt( readln("Введите номер строки k, строки нумеруются с нуля") );
	m = parseInt( readln("Введите номер столбца m, столбцы нумеруются с нуля") );
	if (isNaN(k) || isNaN(m) || m < 0 || k < 0 || k > ARRAY_SIZE - 1 || m > ARRAY_SIZE - 1) {
		writeln("Размер масива " + ARRAY_SIZE + " на " + ARRAY_SIZE  + ", заданые вами индексы выходят за его пределы");
		return;
	}
	writeln("Массив до удаления");
	printArray();
	//удалаем сначала строку, так как это позволит делать меньше итераций при удалении столбца
	array.splice(k, 1);
	//удаляем столбец
	for (i = 0; i < array.length; i++) {
		array[i].splice(m, 1);
	}
	writeln("Массив после удаления");
	printArray();
}

Обратите внимание в объявлении переменных на переменную ARRAY_SIZE. Я использовал только буквы в верхнем регистре для её именования, чтобы дать понять людям, которые будут читать мой код позже, что это именованная константа. К сожалению, JavaScript не поддерживает именованные константы на уровне языка. Во многих других языках, используя специальный синтаксис, можно определить именованную константу по всем правилам. Переписать ее значение далее в коде программы было бы невозможно. Однако именно в этих языках родилась традиция давать имена константе большими буквами - чтобы можно было с первого взгляда понять, что это значение не может менятся в процессе выполнения программы и не стоит даже пытаться присвоить что-то этой "переменной". В JavaScript ничего не мешает переписать значение ARRAY_SIZE в коде ниже, но обычно программисты понимают, видя имя в верхнем регистре, что этого делать не надо.

Зачем вообще нужна эта константа в моем примере? В тексте задачи ничего не сказано о размере, который должен иметь массив, из которого надо удалить строку и столбец. Решая задачу, программист должен быть готов к тому, что вскоре условия задачи изменятся (спросите любого програмиста, это происходит достаточно часто). Если бы в моем примере была не учебная задача а задача из реальной жизни, вполне могло бы случиться, что завтра мне жестко зададут условие, что массив должен быть 256 на 256 элементов, а послезавтра потребуют, чтобы размерность массива вводилась пользователем с клавиатуры.

Так как при инициализации массива я использую значение из ARRAY_SIZE, мне достаточно изменить в первом случае её инициализацию, а во втором используя автозамену редактора кода всюду заменить ARRAY_SIZE на arraySize и добавить получение значения arraySize с клавиатуры.

Далее, после объявления переменных, я заполняю массив случайными значениями. Метод Math random возвращает дробное число от 0 до 1. Однако, я хочу чтобы моя матрица (двумерный массив) аккуратно смотрелась на экране. Поэтому я буду заполнять ее однозначными числами. Я преобразовываю результат работы random в строку и используя тернарную операцию получаю третий символ этой строки, если он существует, если не существует беру 0.

Функция printArray просто проходит по всем элементам массива array, а так как каждый такой элемент является массивом, содержащим в каждом элементе ячейку "строки" прямоугольной матрицы, то во вложенном цикле проходим по такой "строке", собирая все значения в строку s. Для читаемого отображения после каждой "строки" матрицы добавляем в s символ перевода строки '\n'.

Далее, получаем номера удаляемой строки и удаляемого столбца нашего массива, если они выходят за пределы массива, выводим соответствующее сообщение и выходим.

Далее, первым делом удаляем строку двумерного массива, используя метод объекта типа Array splice. Этот метод возвращает копию массива, для которого он вызван, но удаляет в этой копии элементы с индекса указанного в первом аргументе, в количестве, указанном во втором аргументе. Подробнее о методе split можно прочесть здесь. Удалить столбец немного сложнее: надо удалить соответствующий элемент в каждом элементе-массиве массива array. Заключительный цикл в коде программки выполняет эту задачу.

В конце вывожу массив еще раз, чтобы было наглядно видно, что мы действительно удалили строку и столбец.

Тест на новые слова

  • Несохраненный_файл.js
Строка: 0, Символ: 0

  • {name}
  • У вас пока нет файлов
 

Проверьте себя,
знаете ли вы значение слов, использующихся в программном коде на уже прочтенных страницах.

 

Правильно!

Не забывайте переодически проходить этот тест по мере чтения новых статей.

 

Ошибка!

 

Осталось: 0 сек.

Health:

Score:

 

Что значит:

 

 

 


Информация

Загрузите файл с исходным кодом программы на языке яваскрипт.

Файл должен содержать одну главную функцию, имя которой должно совпадать с именем файла.

Например, файл называется task1.js, имя главной функции должно быть task1.

Все остальные функции должны быть определены внутри главной.

*

Информация

Сохраняемый код должен содержать одну главную функцию.

Например:

function myFirstProgram() {
	//Тут все остальное, включая вспомогательные функции
}
					




Простой пароль
Пароли не совпадают