LINUX.ORG.RU

Задачка достаточно сложная :)

 , ,


0

1

Задача:

Предположим, что даны две последовательности букв.

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

Как можно понять сразу для частично вырожденного случая, например - «peal» и «leap» нам просто достаточно поменять местами вершину и дно стека. Но это ведь жульничество так или нет?

А возможен ли здесь универсальный метод решения задачи?!

И да, листинги на Си очень приветствуются :D

★★★★★
Ответ на: комментарий от Twissel

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

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

typedef struct __stack{
	struct __stack *prev;
	char data;
} stack;

int pop(stack **S){
	if(!*S) return -1; // stack is empty
	char r = (*S)->data;
	stack *o = *S;
	if((*S)->prev)
		*S = (*S)->prev;
	else
		*S = NULL;
	free(o);
printf("pop %c\n", r);
	return r;
}

void push(stack **S, char c){
	stack *s = calloc(1, sizeof(stack));
	s->data = c;
	if(!*S) *S = s;
	else{
		s->prev = *S;
		*S = s;
	}
printf("push %c\n", c);
}

int nondestructive_pop(stack **S){
	if(!*S) return -1;
	return (*S)->data;
}

int main(int argc, char **argv){
	char *word, *result, *iptr, *optr, *newword, *nptr, ch;
	stack *S = NULL;
	if(argc != 3){
		printf("Usage: %s word1 word2\n", argv[0]);
		return 1;
	}
	word = strdup(argv[1]);
	result = strdup(argv[2]);
	iptr = word, optr = result;
	if(strlen(word) != strlen(result)){
		printf("Strlen of word1 and word2 should be the same!\n");
		return 2;
	}
	newword = calloc(strlen(result)+1, 1);
	nptr = newword;
	for(; *iptr || S; ){
		ch = *iptr;
printf("compare %c and %c\n", ch, *optr);
		if(ch == *optr){
			*nptr++ = ch;
			optr++;
			iptr++;
			continue;
		}
		if(!S){
			push(&S, ch);
			iptr++;
			continue;
		}
		if(nondestructive_pop(&S) != *optr){
			if(ch){
				push(&S, ch);
				iptr++;
			}else break;
		}else{
			*nptr++ = pop(&S);
			optr++;
		}
	}
	if(strcmp(newword, result)) printf("Impossible!\n");
	else printf("All OK!\n");
	return 0;
}

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от g0t0

Ну в моем случае самому себе, если чё :D

По своему высшему я экономист.

Twissel ★★★★★
() автор топика
Ответ на: комментарий от Twissel

Да не за что. Только надо функции поменять: вместо int пусть char возвращают, а в случае ошибки 0. А то придется доп. проверку вводить.

Eddy_Em ☆☆☆☆☆
()

А может просто кривой перевод? Умеешь показать задачку на языке оригинала, или хотябы скажи как книжка называется и какое издание.

naszar
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.