- •Министерство образования и науки Республики Казахстан
- •Кафедра программного обеспечения
- •Языки программирования
- •Лабораторная работа № 1
- •Краткая теория
- •Задания
- •Лабораторная работа № 2
- •Краткая теория
- •Задания
- •Лабораторная работа №3
- •Краткая теория
- •Задания
- •Лабораторная работа № 4
- •Краткая теория
- •Задания
- •Лабораторная работа № 5
- •Краткая теория
- •Задания
- •Лабораторная работа № 6
- •Краткая теория
- •Объединения
- •Задания
- •Лабораторная работа № 7
- •Краткая теория
- •Задания
- •Лабораторная работа № 8
- •Краткая теория
- •Задания
Задания
31. Дана матрица размера n*m, все элементы которой различны, и вектор из m элементов. Получить скалярное произведение этого вектора на строку, первый элемент которой является минимальным из всех элементов первого столбца.
32. Дана матрица размера n*m, все элементы которой различны. Преобразовать матрицу путем удаления строки и столбца, на пересечении которых расположен минимальный элемент заданной матрицы.
33. Дана квадратная матрица порядка n. Получить скалярное произведение ее диагоналей.
34. Дана матрица размерности n*m. Переставить в ней строки и столбцы таким образом, чтобы самый первый элемент и максимальный элемент при этом поменялись местами.
35. Дана матрица размера n*m из элементов, различных между собой. Преобразовать данную матрицу, удалив из нее ту строку, сумма элементов которой является максимальной из всех строк.
36. Дана матрица размерности n*m. Переставить столбцы этой матрицы в обратном порядке.
37 *. Дана матрица размерности n*m. Удалить из нее те столбцы, в которых есть нулевые элементы.
38 *. Дана матрица размерности n*n. Рассмотрим те элементы, которые расположены в строках, начинающихся с отрицательного элемента. Найти суммы тех их них, которые расположены соответственно ниже, выше и на главной диагонали.
39 *. Дана матрица размерности n*n. Получить линейный массив из n элементов, где каждый i-ый элемент определяется по правилу:
равен сумме элементов i-ой строки, предшествующих первому отрицательному элементу, если в i-ой строке матрицы элемент, принадлежащий главной диагонали, отрицателен;
равен сумме последних элементов i-ой строки, начиная с первого по порядку неотрицательного элемента, в противном случае.
40 *. Дана матрица размера n*m, все элементы которой различны, и вектор, состоящий из m элементов. Элементы первого столбца упорядочены по убыванию. Вставить заданный вектор строкой в матрр строкой в матрм, чтобы упорядоченность по первому столбцу не была нарушена.
Лабораторная работа № 5
Дисциплина: Языки программирования
Тема: Строки
Цель: изучить все функции для работы со строками, уметь правильно применить данные функции в приведенных задачах
Краткая теория
Строка представляется в виде массива символов, где каждый символ строки хранится в отдельной ячейке, а в последней ячейке содержится символ конца строки '\0'. Каждый раз при определении строки мы задаем наибольший размер, который может принять данная строка. Однако в каждый момент времени может быть использована только часть зарезервированной памяти.
char а[ 10];
C |
л |
о |
в |
о |
\0 |
|
|
|
|
Примеры определений строки:
char a[20]; резервируется. 20 байт под массив
char b[20]="строка"; резервируется. 20 байт и заполняются первые 7 включая '\0'
char с[]=" строка"; char *с!="строка";
резервируется 7' байт включая '\0' с - константа-указатель резервируется 7 байт включая '\0' и с - указатель на адрес первого символа, при необходимости этот адрес может быть сменен
Строка может быть инициализирована следующими способами:
сразу при определении :
char а[10]="слово"; '
символ \0 будет добавлен в массив а автоматически
ввод с терминала через функцию scanf с форматной строкой %s scanf("%s",a);
функция считывает все символы до первого разделителя и размещает их в последовательных ячейках массива, автоматически добавляя \0. Из набранной на терминале строки "12 345 67" в строку а попадет "12"
ввод через функцию gets, которая считывает все символы до символа возврата каретки:
gets(a); можно ввести строку "123 asdf 456 пппп"
Со строкой можно работать как с массивом, обращаясь к ее отдельным символам а[0], а[4] и т.д.
Если строки задаются в виде литералов, то компилятор автоматически добавляет символ конца строки '\0', если же строка формируется символ за символом, то добавление в конец строки признака '\0' задача программиста.
а[0]='а';а[1]='Ь';а[2]='\0';
Чтобы работать со строкой как с единым целым, следует использовать функции, описанные в файле string.h:
char * strcat (char* stringl,char *string2);
добавляет в строку, адрес которой задается string2 в конец строки, адрес которой задается значением stringl, записывая в конец строки-результата '\0' и возвращает указатель на сцепленную строку.
char * strncat (char * stringl, char * string2, unsigned n);
добавляет первые n символов строки string2 в строку stringl, завершая результирующую строку '\0' и возвращает указатель на измененную строку.
char * strchr(char * string, int sim);
возвращает указатель на первое местоположение символа, имеющего код sim, в строке string; если символ не найден - результат NULL.
int strcmp(char * stringl, char * string2);
сравнивает строки stringl и string2 и возвращает: меньше 0 - если stringl меньше string2 0- stringl идентично string2 больше 0 - stringl больше string2
int strncmp (char * string 1, cgar * string2, unsigned n);
сравнивает n первых символов в строках string 1 и string2, результаты аналогичны функции strcmp;
int stricmp(char * stringl, char * string2);
аналогична strcmp, но не различаются регистры int strnicmp (char * stringl, cgar * strmg2, unsigned n);
аналогична strncmp, но не различаются регистры char * strcpy (char * stringl, char * string2);
копирует строку string2, включая символ '\0' в строку stringl и возвращает указатель на stringl;
char * strncpy (char* stringl, char * string2, unsigned n);
копирует n первых символов строки string2 в строку stringl, если в строке string2 больше чем n символов, то символ конца строки автоматически не прибавляется, функция возвращает указатель на строку stringl
int strlen(char * string);
возвращает длину строки string в байтах без учета символа '\0'
char * strset(char * string, int sim);
функция присваивает символ sim, заданный кодом, всем символам строки string за исключением завершающего символа '\0' и возвращает указатель на измененную строку
char *strnset(char*,strmg, int sim, unsigned n);
функция присваивает символ sim, заданный кодом, первым n символам строки string и возвращает указатель на измененную строку
char * strrev(char * string);
переписывает строку strung, меняя порядок следования символов на противоположный; завершающий символ '\0' остается на месте; возвращает указатель на измененную строку
char * strrchr(char * string, int sim);
находит последнее вхождение символа sim в строке, символ '\0' включается в поиск, возвращает NULL, если символа нет.
Особо следует отметить, что все эти функции в качестве параметра принимают указатель на тип char, поэтому при определении
chara[10]="abcdefg";
если будет использован указатель а, то функция будет обрабатывать строку с начального символа до \0- "abcdefg", если будет использовано выражение а+3, то функция воспримет строку, начиная с 4-го символа до \0 -"defg".
Не смотря на то, что все эти функции возвращают некоторый результат (чаще указатель на сформированную строку), мы обычно его игнорируем.
Рассмотрим наиболее типичные задачи.
1.
Дана строка, слова в которой разделены пробелами. Определить, есть ли в строке слово заданной длины.
|
В качестве входных данных можно будет вводить строки следующего вида:
"Мама мыла раму"
"На улице давно осень"
"123456789000"
За каждым словом, кроме последнего, стоит пробел. Очевидно, чтобы выполнять работу над каждым очередным словом, можно выбирать все символы до последующего пробела. Чтобы и последнее слово обрабатывалось также, добавим в конец всей строки пробел.
Каждое слово определяется позициями его начального символа и конечного символа: соответственно i и j. Для первого слова i=0.
Чтобы обработать всю строку, необходимо пройти ее от символа с индексом 0 до конца строки (strlen(a)).
Чтобы найти очередное слово, необходимо двигаться по строке до тех пор, пока не будет найден пробел. Зная, что на позиции j расположен пробел, можно утверждать, что слово начинается с символа i и заканчивается на символе j-1. Обрабатывайте полученное слово. Новое слово начнется за пробелом, то есть на позиции i=j+l.
i=0;
for (j=0ij<strlen(a)y++)
if (аШ=' ') { обработка слова на позициях от i до j-1
н |
а |
|
У |
л |
и |
Ц |
е |
|
н |
0 |
Ч |
ь |
|
\0 |
Осталось отметить, что для данной задачи в качестве операции обработки слова будет выступать сравнение его длины с некоторым заданным значением.
Чтобы не выполнять лишних действий, остановим обработку строки как только найдем заданное слово. Для этого введем переменную-признак рг.
include<stdio.h>
mclude<string..h>
main() исходная строка
// заданная длина
//
рг=0 - слово не найдено
int n;
int pr=0;
int ij;
printf("\n введите строку\п");
gets(a);
// добавление последнего пробела в строку а
strcat(a," ");
printf("\n введите требуемую длину слова\п");
scanf("%d",&n);
i=0;
for(j=OJ<strlen(a) && !pr;j
if (аШ== ' ') {
if(j-i==n) pr=l;
if(pr)
printf("\n слово такой длины в строке есть"); else
printf("\n слова заданной длины в строке нет");
}
-
2.Дана строка, слова в которой разделены пробелами. Удалить из нее все слова четной длины.
Подход к решению похож на предыдущую задачу. Необходимо перебрать все слова, с первого до последнего. При этом добавим последний пробел, для единого подхода к выделению всех слов. Как только слово выделено, проверяем его длину на четность. Чтобы удалить слово, фактически необходимо передвинуть на его место остаток строки, следующей за ним. Для этого используем функцию strcpystrcpy(a+i,a+j+l);
н |
а |
|
у |
л |
и |
ц |
е |
|
т |
е |
м |
н |
о |
\0 |
|
|
|
|
|
При удалении i останется прежним и j совпадет с ним.
Поскольку переменная j будет меняться произвольно, и не всегда наращиваться на 1 от шага к шагу, удобнее использовать цикл while вместо цикла for.
#include<stdio.h>
include<string.h>
main()
{
char a[30]; // исходная строка
intij;
printf("\n введите строку \п"); gets(a);
strcat(a," "); // добавление последнего пробела в строку а
i=; j=;
while(j<strlen(a) ) if (aO]==' ')
{
if ((ji)%2 == 0)
{ strcpy(a+i,a+j+l);
else
j++;
printf("\n
3. Дана строка, слова в которой разделены пробелами. Получить новую строку из исходной, переставив местами первое и последнее слово строки.
В задаче задействованы две строки. Исходная строка получает значение через ввод пользователя. Результирующая строка формируется программой.
Фактически чтобы выделить из строки первое и последнее слово достаточно определить индексы первого и последнего пробелов в ней. Тогда первое слово определиться между индексами 0 и индексом первого пробела, последнее слово - между индексом последнего пробела и последним символом строки.
// поиск первого пробела
i=0;
while (a[i]!=' ')
i++;
//поиск последнего пробела j=strlen(a)-l;
while (a[j]!=' ')
j--;
0
н |
а |
|
в |
е |
р |
х |
у |
|
б |
ы |
л |
о |
|
т |
е |
м |
н |
о |
\0 |
strlen(a)
Результирующая строка изначально пуста :
charb[30]=’’ ’’;
Затем в нее помещается последнее слово строки а и пробел
strcat(b,a+j);
strcat(b," ");
Далее размещаются все слова между первым и последним словом (обратите внимание на правильное расположение пробелов)
strncat(b,a+i+l,j-i);Последним в строку b добавляется первое слово строки а
strncat(b,a,i);
Помните, что функции strcat и strncat символ \0 добавляют в конец новой строки автоматически. Обратите внимание, что вывод результирующей строки осуществляется функцией puts.
include<stdio.h>
inciude<string.h> main()
{
char a[30]; // исходная строка
char b[30]=""; // результирующая строка
int i,j;
printf("\n введите строку \n");
gets(a);
// поиск первого пробела
i=0;
while (a[i]!=' ')
i++;
// поиск последнего пробела j=strlen(a); while (a[]]!=' ')
j--;
// формирование результирующей строки
strcat(b,a+j);
strcat(b,"");
stmcat(b,a+i+lj-i);
strncat(b,a,i);
puts(b);
}
