Решение ряда задач.

SashaMercury
Дата: 25.11.2014 04:14:30
Здравствуйте.
Случайно наткнулся в журнале на задачи от одной компании, (название которой я писать не буду ибо не хочу что-то пиарить, пусть и на фоне), и решил размяться Да, решения этих задач можно отправить в компанию, не знаю зачем, какие-то призы вероятно, но срок уже истек, это сентябрьский номер, так что вы не подумайте что я преследую личную выгоду от того, что спрашиваю у вас что-либо по этому поводу.

Вообще дано 6 задач. Сейчас решил первую.
задача 1
Дана строка "Hello, Embarcadero". Не обращая внимание на производительность, написать как можно больше вариантов , как поменять символы местами в обратном порядке. Варианты могут отличаться лишь синтаксисом. Можно использовать библиотечные функции работы со строками, но должны быть варианты и без них.
\

Вот как я её решил

1 вариант
#include <stdio.h>
#include <string.h>

int swap_2symb(char* a, char* b)
{
	char t = *a;
	*a = *b;
	*b = t;
	return 0;
}

int reverse_in_place(char* s, size_t p)
{
	for (size_t i=0; i < p / 2; ++i)
		swap_2symb(s + i, s + p - 1 - i);

	return 0;
}


int main()
{
	char s[] = "Hello, Embarcadero";
	printf("before: %s\n", s);
	reverse_in_place(s, strlen(s));
	printf("after: %s\n", s);
	return 0;
}


2 вариант, аналогично, но реализовал функцию strlen

#include <stdio.h>


size_t strlen(const char* s)
{
	size_t p = 0;
	while (*s++)
		++p;

	return p;
}


3 вариант
int reverse_in_place(char* res, const char* s, size_t p)
{
	for (size_t i = 0; i < p; ++i)
		*(res + p - 1 - i) = *(s + i);

	*(res + p) = '\0';
	return 0;
}

char* reverse(const char* s)
{
	size_t p = strlen(s);
	char* res = (char*)malloc(sizeof(char)*(p+1));
	reverse_in_place(res, s, p);
	return res;
}


4 вариант, тут добавил указатели
int reverse_in_place(char* res, const char* s, size_t p)
{
	for (int i = p - 1; i >= 0; --i)
		*res++ = *(s + i);

	*res = '\0';
	return 0;
}


можно еще написать функцию принимающую адреса начала и конца строки, и делать её реверс, можно сделать реверс каждого слова, можно своп делать по-другому. Других вариантов в голову не приходит. Но ведь должен быть в задаче подвох ? Она кажется слишком простой. Как бы вы её решали ?
Кстати, в условии задачи меня смутила фраза про производительность. Что авторы хотели этим сказать ?

PS
остальные 5 задач выложу позже.
mayton
Дата: 25.11.2014 09:24:23
На производительность вляют столько факторов что топика не хватит.
Я-бы предложил подумать над оптимизациями идущими далеко в будущее.

1) Всегда-ли нужно свапировать? Может быть строка уже зеркально-симметрична
Я исхожу из предположения что запись в память - дорого стоит с точки
зрения кешей и синхронизаций. И лучше ее (запись) вообще не делать
до самого последнего времени. Максимальная иммутабельность.

2) Предлагаю вообще не свапировать длинные строки (более 255 символов к примеру).
Но хранить для них булево свойство.

bool isSwapped=false;


Если кто-то если захочет получить распечатать строку на экране или получить
перевёрнутый порядок - то мы ему отдадим геттер или итератор который
вернёт символы в том порядке который соответствует isSwapped.
Это отчасти соответствует принципам lazy-evaluation.

Методы конкатенаций и поиска подстрок также должны учитывать свойство
isSwapped.

Предлагаю также считать верным тезисы

reverse(reverse(A)) == A


Если строка - является палиндромом или из 1 символа то

reverse(A)==A


Признак палиндромности isPalindrom=true можно также хранить в объекте строки.

3) Возможно существуют и низкоуровневые (ассемблерные) оптимизации этой задачи
основанные на знаниях команд современных CPU и возможностей железа в плане
управления кешами.

Вобщем у меня - всё.

Задача в чистом виде - тоесть именно свапирование букв в memory мне кажется
ненужной. Тем более что в форуме эта задача уже звучала.
MasterZiv
Дата: 25.11.2014 11:05:04
Ну вы вообще...
Не каждый сможет обратить строку, в смысле, делать это могут не только лишь все...
Anatoly Moskovsky
Дата: 25.11.2014 12:07:28
mayton
На производительность вляют столько факторов что топика не хватит.
Я-бы предложил подумать над оптимизациями идущими далеко в будущее.

Вообще-то в условии задачи прямо сказано что производительность не важна :)

Это задача на умение генерировать идеи.
no56892
Дата: 25.11.2014 12:28:36
А еще есть вариант рандомно перемешивать массив символов до тех пор, пока там не появится "строка наоборот".
mayton
Дата: 25.11.2014 12:35:33
Будь здесь Базист - он предложил-бы загнать все строки известные науке в его магическую
флористическую базу и вместо реверса просто находить ответную строку через
ультра-быстрый поиск.
Dimitry Sibiryakov
Дата: 25.11.2014 12:39:23

SashaMercury
Но ведь должен быть в задаче подвох ?

Подвох номер 1: про системную функцию ReverseString() они не зря упомянули.
Подвох номер 2: про "in-place" нигде не сказано, следовательно простейшим методом будет
копирование в новый буфер.

Ну и странно, что тебе не пришёл в голову простейший вариант:
char* end = strchr(str,0);
while (str < end)
{
   char c = *str;
   *str++ = *--end;
   *end = c;
}

Posted via ActualForum NNTP Server 1.5

Изопропил
Дата: 25.11.2014 12:58:20
Dimitry Sibiryakov
следовательно простейшим методом будет

что есть "простейший" ?
mayton
Дата: 25.11.2014 13:04:31
Дима. Дык твой код вроде как сделает двойной реверс. Не?
mayton
Дата: 25.11.2014 13:08:45
Вроде не.