Архив метки: массив

Массив разных случайных чисел

С++Задача:

Заполнения массива случайными неповторяющимися элементами числами (язык Си)

Решение:

Алгоритм решения заполнения массива содержит три цикла: в первом цикле выбираем номер заполняемого элемента (переменная i); внутри первого цикла выполняется второй цикл (do…while), который будет выполняться еще раз, если потребуется повтор; внутри цикла (do…while) выполняются еще три действия: вычисляется значение нового элемента, переменной x задается значение «не повторять» и запускается третий цикл – сравнения вычисленного значения со всеми предыдущими (цикл for по переменной j).

Листинг решения:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#define N 20 //количество элементов в массиве
#define Povtor 1 //есть ли повторения

inline void rus() // Русификация вывода в консольное окно
{
setlocale( LC_CTYPE, ".1251" );
setlocale( LC_MONETARY, ".1251" );
}
void randomize()
{
srand(time(0));
}

unsigned int random(int range)
{
return (rand() % range);
}

int main()
{
char c[N];
int i, j, x,range;

rus();
randomize();
printf("Заполнение одномерного массива символами \n");
printf("в случайном порядке. Символы не должны повторяться. \n");
printf("Коды символов расположены в диапазоне от 33 до 90.\n");

range = 90-33+1;
*c=random(range) + 33; // Первый элемент

for (i=1;i<N; i++) // Цикл заполнения элементов,
{ // i – номер очередного элемента
do
{
*(c+i)=random(range) + 33; // Новое значение
x = !Povtor; // Считаем, что повтор поиска не нужен
for(j=0; j<i; j++) // Цикл сравнения со всеми предыдущими
if (*(c+i)==*(c+j))
{
x = Povtor; // Элементы совпали, надо повторить поиск
break;
}
}
while (x==Povtor);
}
// Вывод одномерного массива символов
printf("Распечатка массива \n");
for (i=1; i<N; i++) //заметьте еще раз, проверяется условие i<N
printf("%c",(*(c+i)));
return 0;
}

Можно также реализовать функцию, проверяющая повторился ли элемент y в массиве x или нет, к примеру может иметь следующий вид (считаем, что количество элементов в массиве x равно n).

Листинг примера функции для поиска повторяющегося элемента

int povtor(int *x, int n, int y)
{ int Povtor, i;
Povtor = 0;
for (i=0;i<n;i++) {if (x[i]==y) Povtor=1;}
return Povtor;
}

Вывод каталога используя smarty

Smarty ШаблонизаторИтак необходимо реализовать вывод каталога с подкаталогами неограниченной вложенностью, используя шаблонизатор smarty.

Один из способов:

1. Прежде чем начать необходимо иметь таблицу в нашей БД с необходимыми данными. К примеру как на рисунке ниже.

Таблица MySql для реализации вывода каталогов2. Теперь пишем необходимый php код в файле index.php
в комментариях необходимые пояснения

require('../libs/Smarty.class.php'); //подключение smarty

include "authBD.php"; //в этом файле подключаем БД

$smarty = new Smarty; // создаем объект шаблонизатора

// создаем текст запроса для выборки из нашей БД
$query = "select * from category"; 

// делаем выборку и заносим в массив
$result_table  = mysql_query($query) or die(mysql_error());
$rows_array=array();
while ($row=mysql_fetch_array($result_table))
   $rows_array[]=$row;

//формируем дерево из выборки
 $cat_tree=select_to_array_tr($rows_array); 

//создаем переменную для нашего дерева каталогов
$smarty->assign('cat1', $cat_tree);

//вызываем шаблон
$smarty->display('index.tpl');

3. Формирования дерева из массива выборки

Функция не использует рекурсию, основана на ссылках, в child хранятся подкаталоги если они есть у родителя.

Листинг

function select_to_array_tr($arr,$mk='Id_cat',$sk='Id_parent',$child='child')
{  // если нет создаем
    if(!$arr) {
        return array();
    }

    $mas = array();
    $l = count($arr); //кол-во элементов в массиве
    for($i = 0; $i < $l; $i++) {
        $mas[ $arr[$i][$mk] ] = &$arr[$i];
    }
    // child - массив дочерних каталогов
    foreach($mas as $k => $v) {
        $mas[ $v[$sk] ][$child][] = &$mas[$k];
    }

    $res = array();
    foreach($arr as $v) {
        if(isset($v[$sk]) && $v[$sk] == 0) {
            $res[] = $v;
        }
    }
//возвращаем готовый массив
     $arr = $res;
    return $arr;
}

необходимо добавить ее в наш файл index.php перед ее вызовом.

4. Необходимо отредактировать шаблон index.tpl, он находится в папке templates.

Листинг шаблона index.tpl

<ul>
{foreach item='ListTree' from=$cat1}
{* вывод корневых каталогов *}   
     <li>{$ListTree.Name}    </li>
{* вывод подкаталогов используется рекурсия шаблонов *}
    {if count($ListTree.child)>0}
        {include file='ListTree.tpl' object=$ListTree}
    {/if }    
{/foreach}
</ul>

5. Затем создадим файл ListTree.tpl со следующим кодом(ниже) и сохраним в папке templates. Этот шаблон будет вызываться для всех дочерних каталогов.

Листинг шаблона ListTree.tpl

<ul>
{foreach item='ListTree' from=$object.child}
{* вывод корневых каталогов *}
     <li>{$ListTree.Name}    </li>
{* вывод подкаталогов используется рекурсия шаблонов *}
    {if count($ListTree.child)>0}
        {include file='ListTree.tpl' object=$ListTree}
    {/if }
{/foreach}
</ul>

Результат получается такой

Вывод каталога используя Smarty

Распространенные функции для работы со строками С++

С++Функции для работы со строками

Для преобразования строк в языке Си предусмотрена библиотека string.

Каждая из функций имеет свой формат записи (прототип). Некоторые из функций представлены ниже.

 

void *strcat(char *s1,const char *s2) – дополняет строку s1 строкой s2.

char *strncat(char *s1,const char *s2, size_t n) – дополняет строку s1 символами из строки s2, но не более чем n штук.

char *strcpy(char *s1,const char *s2) – копирует строку, указанную указателем s2, на место, указанное указателем s1; возвращает s1.

char *stpcpy(char *dest, const char *src) – копирует строку, указанную указателем src, на место, указанное указателем dest; не копирует символ конца строки;

char *strncpy(char *s1, const char *s2, size_t n) – копирует строку, указанную указателем s2, на место, указанное указателем s1; возвращает s1; копируется не более чем n символов.

int strcmp(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2; символы строк сравнивают с помощью значений их кодов; функция возвращает 0, если строки одинаковы; значение, которое меньше 0, если первая строка меньше второй; и значение, превышающее 0, если первая строка больше второй.

int strncmp(const char *s1,const char *s2, size_t n ) – сравнивает первые n символов или до первого пустого символа строки, указанные указателями s1 и s2.

int stricmp(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2, игнорируя регистр символов (строчные или заглавные);

int strcmpi(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2, игнорируя регистр символов (строчные или заглавные);

char *strchr(const chat *s, int c) – ищет первое появление c (преобразованного в char) в строке, указанной указателем s; пустой символ является частью строки; возвращает указа-тель на первое появление или NULL, если ничего не найдено.

char *strrchr(const chat *s, int c) – ищет последнее появление символа c в строке, то есть поиск идет с конца строки, заданной указателем s; пустой символ является частью строки; возвращает указатель на первое появление или NULL, если ничего не найдено.

char *strstr(const chat *s1, const char *s2) – возвращает указатель на положение первого появления последовательности символов из s2 в строке s1 (исключая завершающие про-белы); возвращает NULL, если совпадений не найдено.

char *strtok(chat *s1,const chat *s2) – эта функция переформирует строку s1 в отдельные знаки; строка s2 содержит символы, которые используются в качестве разделителей. Функция вызывается последовательно. Для первого вызова s1 должен указывать на стро-ку, которую необходимо разбить на знаки. Функция находит разделитель, который следует за символом, не являющимся разделителем, и заменяет, его пробелом. Она возвращает указатель на строку, содержащую первый знак. Если ни оного знака не найдено, она воз-вращает NULL. Чтобы найти следующий знак в строке, необходимо вызвать функцию опять, но первым аргументом поставить NULL. Каждый последовательный вызов возвращает указатель на следующий знак или на NULL, если больше знаков не найдено.

int strlen(const char *s) – возвращает число символов (исключая завершающие пробелы) в строке s.

void setmem(void *dest, unsigned length, char value) – присваивает значение value диапа-зону памяти, начиная с адреса dest;

size_t strspn(const char *s1, const char *s2) – находит начальный сегмент строки s1, кото-рая состоит из символов строки s2; возвращает длину найденного сегмента.

size_t strсspn(const char *s1, const char *s2) – находит начальный сегмент строки s1, ко-торая не состоит из символов строки s2; возвращает длину найденного сегмента.

char *strdup(const char s) – резервирует оперативную память и помещает на это место копию строки s; возвращает указатель на зарезервированную область памяти.

char *strlwr(char *s) – преобразует все символы строки к нижнему регистру (от a до z); возвращает указатель на строку s.

char *strupr(char *s) – преобразует все символы строки к верхнему регистру (от A до Z); возвращает указатель на строку s.

char *strpbrk(const char *s1, const char *s2) – сканирует строку s1 на присутствие любого символа строки s2; возвращает указатель
на найденный символ или NULL, если совпаде-ние не найдено.

char *strrev(char *s) – переписывает символы в строке в обратной последовательности; возвращает указатель на строку s.

char *strset(char *s, int ch) – все символы в строке делает равными ch; возвращает указа-тель на строку s.

size_t strxfrm(char *s1, char *s2, size_t n) – символы строки s2 заменяет на соответствующие символы строки s1, но не более чем n символов; возвращает количество замененных символов.

Преобразования одномерных массивов байтов памяти

Кроме функций для работы со строками в библиотеке string есть ряд функций для преобразования одномерных массивов байтов памяти:

int memcmp (const void *s1, const void *s2, size_t n) – сравнивает два блока памяти, начинающиеся с адресов s1 и s2, но не более, чем n байтов; возвращает 0, если блоки рав-ны, число меньшее 0, если первый блок меньше второго, число большее 0, если первый блок больше второго.

void *memcpy (void *dest, const void *src, size_t n) – копирует блок памяти src в блок памяти dest, но не более, чем n байтов; если блоки пересекаются, то результат не определен.

void *memccpy(void *dest, const void *src, int c, size_t n) – копирует блок памяти src в блок памяти dest; копирование останавливается по достижении количества в n байтов или после копирования символа c.

void *memmove(void *dest, const void *src, size_t n) – копирует блок памяти src в блок памяти dest, но не более, чем n байтов; копирование корректное даже если блоки памяти пересекаются.

void *memchr (const void *s, int c, size_t n) – в блоке памяти в n байтов ищет символ c, начиная с адреса s; если символ найден – возвращается указатель на найденный элемент, в противном случае NULL.

Пример работы с этими функциями — Пример №1(листинг) | Пример№2 (Листинг)

Си — работа со строками

Си работа со строками

Объявление строк

Строка в языке Си представляет собой одномерный массив символов, последним элементом которой является символ конца строки – нуль (строка, завершающаяся нулем, то есть NULL terminated string).

Объявление переменной типа строка в языке Си возможно тремя способами, два из которых инициализируют строку во время объявления.

Первый способ:

Объявления массива символов (не забудьте добавить место для завершающего нуля):

char s[40+1];

Второй способ:

Присвоить строковой переменной начальное значение (при этом длину строки компилятор может вычислить сам):

char s[] = "Пример инициализации строки";

Справа от знака присваивания записана строковая константа. В конце строки автоматически добавляется ноль (‘\0’). Константы символьных строк помещаются в класс статической памяти.

Третий способ:

Неявное указание, что используется массив. В левой части от знака присваивания указывается указатель на символ:

char *s="Второй вариант инициализации";

Переменная s будет указателем на то место в оперативной памяти, где располагается строковая константа. В такой форме записи кроется потенциальная ошибка, заключающаяся в том, что указатель на  символ часто называют строкой. Представленная ниже запись – это только указатель на символ, так как для размещения строки место не предусмотрено:

char *s;

Ввод строки со стандартного устройства ввода (клавиатуры)

Для работы со строками есть набор функций. Для ввода со стандартного устройства ввода (клавиатуры) чаще всего используются библиотечные функциями из модуля стандартного ввода-вывода: scanf и gets.

Для ввода строки с помощью функции scanf, использует формат «%s», причем обратите внимание на то, что перед идентификатором строки не используется знак адреса «&», так как одномерный массив уже представлен указателем на его начало:

scanf("%s", s);

Функция gets() считывает символы до тех пор, пока не достигнет символа перехода на новую строку. Функция принимает все символы вплоть до символа перевода строки, но не включает его. К концу строки добавляется завершающий ноль (‘\0’). Функция gets() помещает считанную с клавиатуры последовательность символов в параметр типа строка и возвращает указатель на эту строку (если операция завершилась успешно), или NULL (в случае ошибки). В приведенном ниже примере при успешном завершении операции, на экран будет выведено две одинаковые строки:

#include <stdio.h>
int main()
{  char s[50];
char *p;
p=gets(s);
printf(" \n Введена строка %s. ",s);
if (p) printf(" \n Введена строка %s. ",p);
return 0;
}

Попутно заметим, что функция gets часто используется для ввода лю-бых данных с клавиатуры в виде строки с целью дальнейшего преобразования функцией sscanf к нужному формату или для предварительного анализа вводимых данных, например:

#include <string.h>
#include <stdio.h>
#include <conio.h>
int main()
{ char s[50];   int x, err;
do
   {   printf(" \n Введите целое число -> ");
       gets(s);
       err=sscanf(s, "%d",&x);
       if (err!=1) printf(" \n Ошибка ввода. ");
  } while (err!=1);
  printf("\n Введено целое число -> %d", x);
return 0;
}

Вывод строк на стандартное устройство вывода (экран монитора)

Для вывода строк на стандартное устройство вывода (экран монитора) можно использовать две функции printf и puts. В функции printf в качестве формата передается «%s». Удобство использования этой функции заключается в том, что помимо строки можно сразу выводит данные других типов. Особенность функции puts заключается в том, что после вывода строки автоматически происходит переход на следующую строку.

Функции для работы со строками

Для преобразования строк в языке Си предусмотрена библиотека string. Каждая из функций имеет свой формат записи (прототип).

Наиболее  используемые функции рассмотрены в этой статье. — читать

Пример программ(листинг) работающей со строками

Пример №1(листинг) | Пример№2 (Листинг)

Листинг обработок строк в С++

Тема:  Обработка символьных массивов

Задание

Во введенном предложении расположите слова в обратной последовательности. Порядок следования знаков препинания не менять.
В предложении используются русские буквы и знаки.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

#define N 20

  //  ПРЕДВАРИТЕЛЬНОЕ ОБЪЯВЛЕНИЕ ФУНКЦИЙ
  // Заголовок программы
      void Title();
  // Ввод предложения
      void InpPredl (char predl[]);
  // Выделение из предложения
     void Select(const char *predl, char m[][N],char *sel, int *n);
  // Сборка предложения
     char *Constructor(char slova[][N], char razd[][N], int sl, int rz);
  // Вывод результата
     void OutPredl(char *s1, char *s2);

inline void rus()  // Русификация вывода в консольное окно
{
    //setlocale( LC_CTYPE, ".1251" );
    //setlocale( LC_MONETARY, ".1251" );
    setlocale( LC_ALL, "" );
}

// ОСНОВНАЯ ФУНКЦИЯ
int main()
{
     // ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ
  char predl[80];    // Введенное предложение
  char *res;            // Результирующее предложение
  char slova[N][N]; // Массив слов в предложении
  char razd [N][N]; // Массив разделителей в предложении
  int  sl=-1, rz=-1;  // Счетчики слов и разделителей
  char buk[80]; // все буквы алфавита
  char *bs="йцукенгшщзхъфывапролджэячсмитьбю";// Буквы строчные
  char *bz ="ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ";/*  заглавные */
  char *r="`!;:,.?- _";         // Разделительные знаки
//ВЫЗОВ ФУНКЦИЙ НА ИСПОЛНЕНИЕ
    rus();
// Заголовок программы
       Title ();
  // Ввод предложения
       InpPredl (predl);
  // Выделение из предложения слов
      Select (predl, slova, r, &sl);
  // Выделение из предложения разделителей
      strcpy(buk,"");
      strcat (buk, bs);
      strcat (buk, bz);
      Select (predl, razd, buk, &rz);
  // Сборка предложения
      res = Constructor(slova, razd, sl, rz);
  // Вывод результата
     OutPredl (predl, res);
  free (res);
    return 0;
}


// ОПИСАНИЕ ИСПЛЬЗУЕМЫХ ФУНКЦИЙ
// Заголовок программы
void Title()
{
  puts (" Задание  по теме\n");
  
}
// Ввод предложения
void InpPredl(char *s)
{
  puts("Введите предложение \n");
  strcpy (s,"Верите ли вы, что задача решена?");
  // gets (s);
}
// Вывод результата
void OutPredl (char *s1, char *s2)
  {
    puts ("Исходное предложение");
    puts (s1);
    puts (" Результат ");
    puts (s2);
  }
// Выделение из предложения
void Select(const char *predl, char m[][N], char *sel, int *n)
{
  char *p, *s;

  s=strdup (predl); // Сделать копию исходного предложения
	// так как передается константа, strtok требует
	// внесения изменений при своей работе
  p = strtok (s, sel);
  while (p)
    {
     (*n)++;
     strcpy (m[*n],p);
     p = strtok (NULL, sel);
    }
  free (s);
}
// Сборка предложения
char *Constructor(char slova[][N], char razd[][N], int sl, int rz)
{
  int i, j;
  char res[80];
  char *s;
*res=0; // Начальное значение результата
   i = sl;
   j=-1;
  while ((i>=0)||(j<=rz))
    {
      if ((i>=0)) strcat (res, slova[i]); // Добавление слова
      i--;
      j++;
      if ((j<=rz)) strcat (res, razd[j]); // Добавление знаков
    }
  s = strdup (res);
  return s;
}