Added a bunch of exercises
This commit is contained in:
parent
fa336b47ff
commit
ecde13ada2
|
@ -48,7 +48,7 @@
|
|||
|
||||
- [ ] Endereços e ponteiros
|
||||
|
||||
- [ ] Alocação dinâmica d ememória
|
||||
- [ ] Alocação dinâmica de memória
|
||||
|
||||
- [ ] Leitura de linhas de texto
|
||||
|
||||
|
@ -66,6 +66,4 @@
|
|||
|
||||
- [ ] Pré-processamento
|
||||
|
||||
- [ ] Ferramentas e utilitários
|
||||
|
||||
|
||||
- [ ] Ferramentas e utilitários
|
|
@ -0,0 +1,94 @@
|
|||
# Logaritmos
|
||||
|
||||
## Exercícios 2
|
||||
|
||||
**1.** Prove os dois invariantes da primeira versão da função lg:
|
||||
|
||||
```c
|
||||
int lg (int N)
|
||||
{
|
||||
int i, n;
|
||||
i = 0;
|
||||
n = 1;
|
||||
while (n <= N/2) {
|
||||
n = 2 * n;
|
||||
i += 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
```
|
||||
|
||||
Um invariante é uma propriedade a qual invariavelmente é verdadeira durante toda a execução de um *loop*, de tal forma que a corretude deste pode ser demonstrada se a invariante se mantêm verdadeira
|
||||
|
||||
- antes da iteração inicial ($i = 0$),
|
||||
|
||||
- para cada iteração subsequente (se verdadeira em $i = k$, também o é para $i = k + 1$)
|
||||
|
||||
- e ao término do *loop* ($i = n$, onde $n$ é o valor de parada)
|
||||
|
||||
Para o algoritmo acima, seja $N \in \N$, temos como invariantes que $n \le N$ e $i = \log_2n$.
|
||||
|
||||
**Prova**
|
||||
|
||||
Para $n$ temos:
|
||||
|
||||
- **Inicialização:** Para $N = 1$, $n_0 = 1$, então $n_0 \le N$.
|
||||
|
||||
- **Manutenção:** Para $N = k$ na iteração $x$, $x > 0$, assumimos $n_x \le k/2$. Ai para iteração $x + 1$ temos que o valor de $n_{x + 1} = 2n_x$. Como $n_x \le k/2$, tem-se que $n_{x + 1} \le k$, ou seja, $n_{x + 1} \le N$.
|
||||
|
||||
- **Término:** Para se encerrar na iteração $x$ tem-se que $n_x > N/2$ seja porque $n = N = 1$ ou, senão, porque $n_x > N \div 2$ quando $n_{x - 1} \le N/2$. No primeiro caso nada resta a demonstrar, mas no segundo caso segue que $n_x = 2n_{x - 1}$, então
|
||||
|
||||
$$
|
||||
n_{x - 1} \le N/2 \stackrel{\times 2}{\implies} 2n_{x - 1} \le N \implies n_x \le N
|
||||
$$
|
||||
|
||||
Para $i$ temos:
|
||||
|
||||
- **Inicialização:** Para $N = 1$, $n_0 = 1$ e $i_0 = 0$, então $i_0 = \log_2 n_0$.
|
||||
|
||||
- **Manutenção:** Para $N = k$ na iteração $x$ assumimos que $n_x \le k/2$ e $i_x = \log n_x$, para a iteração $x + 1$ temos que o valor de $n_{x+1} = 2n_x$ e $i_{x+ 1} = i_x + 1$. Logo,
|
||||
|
||||
$$
|
||||
\log_2n_{x + 1} = \log_22n_x = \log_2n_x + \log_22
|
||||
= i_x + 1 = i_{x + 1}
|
||||
$$
|
||||
|
||||
- **Término:** Para se encerrar na iteração $x$ tem-se que $n_x > N/2$ seja porque $n = N = 1$ ou, senão, porque $n_x > N \div 2$ quando $n_{x - 1} \le N/2$. No primeiro caso $i = 0$ nada resta a demonstrar, mas no segundo caso segue que $n_x = 2n_{x - 1}$ e $i_{x - 1} = \log_2n_{x - 1}$, então
|
||||
|
||||
$$
|
||||
\log_2n_x = \log_22n_{x - 1} = \log_2n_{x - 1} + \log_22
|
||||
= i_{x - 1} + 1 = i_x
|
||||
$$
|
||||
|
||||
**2.** Invariantes: $1 \le n \le N$ e $i \le \log_2N$. A demonstração é análoga a anterior. Pode ser feita aqui subsequentemente havendo tempo.
|
||||
|
||||
**3.** Vide `lg.c`
|
||||
|
||||
**4.** O que faz a função abaixo? Escreva o invariante que explica a função.
|
||||
|
||||
```c
|
||||
int tlg (int N) {
|
||||
int i = 0, n = 1;
|
||||
while (n < N) {
|
||||
n *= 2;
|
||||
i += 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
```
|
||||
|
||||
Essa é a função que apresenta o resultado de $\lceil \log_2N \rceil$. Os invariantes são $n < 2N$ e $i = \log_2 n$.
|
||||
|
||||
**5.** O que é o *teto* de um número real $r$? Se $R$ é um número estritamente positivo, qual a relação entre o teto de $log_{10} R$ e $R$? Escreva uma função recursiva que receba um número inteiro estritamente positivo $N$ e devolva o teto de $log_{10} N$.
|
||||
|
||||
O menor número inteiro $i$ tal que $i \ge r$. O teto do $\log_{10}R$ fornece o número de dígitos necessários a representar a parte inteira de $R$ em números decimais. Vide `lg.c`.
|
||||
|
||||
## Exercícios 3
|
||||
|
||||
1. Sim.
|
||||
|
||||
2. Vide `overflow.c`
|
||||
|
||||
3.
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int getValue(char *varName) {
|
||||
int i = -1;
|
||||
|
||||
printf("Type in a value to %s: ", varName);
|
||||
scanf(" %d", &i);
|
||||
return i;
|
||||
}
|
||||
|
||||
int flg(int n, int base) { return (n > 1) ? flg(n / base, base) + 1 : 0; }
|
||||
|
||||
int clg(int n, int base) {
|
||||
return flg(n, base) + ((n > base && n % base > 0) ? 1 : 0);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n, b;
|
||||
char option[8];
|
||||
|
||||
printf("This program calculates the floor or ceiling of the logarithm of n "
|
||||
"with a "
|
||||
"base of b, n and b being natural numbers, and b > 2.\n");
|
||||
|
||||
if ((n = getValue("n")) < 1) {
|
||||
printf("Invalid value for n: not a natural number\n");
|
||||
return 1;
|
||||
}
|
||||
if ((b = getValue("b")) < 2) {
|
||||
printf("Invalid value for b: not a valid logarithm base\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Which would you like to calculate? The [f]loor or [c]eiling? ");
|
||||
scanf("%7s", option);
|
||||
if (!strcmp("f", option) || !strcmp("floor", option))
|
||||
printf("%d\n", flg(n, b));
|
||||
else if (!strcmp("c", option) || !strcmp("ceiling", option))
|
||||
printf("%d\n", clg(n, b));
|
||||
else {
|
||||
printf("Invalid option: \"%s\"\n", option);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void clearJunk(char *c) {
|
||||
*c = getchar();
|
||||
if (!isdigit(*c))
|
||||
clearJunk(c);
|
||||
}
|
||||
|
||||
char *readNumber(int *n) {
|
||||
int i = 0, size = 1;
|
||||
char c, *number = malloc(sizeof(char));
|
||||
errno = INT_MAX;
|
||||
|
||||
clearJunk(&c);
|
||||
while (isdigit(c)) {
|
||||
if (i == size - 1) {
|
||||
size *= 2;
|
||||
number = realloc(number, size * sizeof(char));
|
||||
}
|
||||
number[i++] = c;
|
||||
c = getchar();
|
||||
}
|
||||
number[i] = '\0';
|
||||
*n = strtoimax(number, NULL, 10);
|
||||
return number;
|
||||
}
|
||||
|
||||
int main() {
|
||||
char *number;
|
||||
int n;
|
||||
|
||||
printf("This piece of code detects if the square power of a number "
|
||||
"produces an overflow, otherwise it is printed normaly.\nType in a "
|
||||
"number to test it: ");
|
||||
number = readNumber(&n);
|
||||
if (n > INT_MAX / n)
|
||||
printf("%s ⨉ %s produces an overflow.\n", number, number);
|
||||
else
|
||||
printf("%d ⨉ %d = %d\n", n, n, n * n);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void flushInput() {
|
||||
int c;
|
||||
if ((c = getchar()) != '\n' && c != EOF)
|
||||
flushInput();
|
||||
}
|
||||
|
||||
int *resizeArray(int *array, int *buffer) {
|
||||
*buffer *= 2;
|
||||
return realloc(array, *buffer * sizeof(int));
|
||||
}
|
||||
|
||||
int *readInput(int *size, int *buffer) {
|
||||
int i, value, *array = NULL;
|
||||
*buffer = 1;
|
||||
|
||||
for (i = 0; scanf(" %d", &value); array[i++] = value)
|
||||
if (i == *buffer - 1)
|
||||
array = resizeArray(array, buffer);
|
||||
flushInput();
|
||||
*size = i;
|
||||
return array;
|
||||
}
|
||||
|
||||
void shift(int *array, int start, int end, int increment) {
|
||||
if (start == end)
|
||||
return;
|
||||
array[start] = array[start + increment];
|
||||
shift(array, start + increment, end, increment);
|
||||
}
|
||||
|
||||
int pop(int **array, int index, int *size) {
|
||||
int value;
|
||||
|
||||
if (index >= *size || index < 0)
|
||||
return EOF;
|
||||
value = (*array)[index];
|
||||
if (index > *size - index)
|
||||
shift(*array, index, *size - 1, 1);
|
||||
else
|
||||
shift((*array)++, index, 0, -1);
|
||||
(*size)--;
|
||||
return value;
|
||||
}
|
||||
|
||||
int *insert(int value, int index, int *array, int *size, int *buffer) {
|
||||
if (index > *size) {
|
||||
printf("Invalid index: index not in range 0 to %d", *size);
|
||||
} else {
|
||||
if (*size == *buffer - 1)
|
||||
array = resizeArray(array, buffer);
|
||||
shift(array, (*size)++, index, -1);
|
||||
array[index] = value;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
int iteractiveRemoveZeroes(int *array, int size) {
|
||||
int i, j;
|
||||
for (i = j = 0; j < size; j++)
|
||||
if (array[j] != 0)
|
||||
array[i++] = array[j];
|
||||
return i;
|
||||
}
|
||||
|
||||
int removeZeroes(int *array, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
pivot = removeZeroes(array, --size);
|
||||
if (array[size] != 0)
|
||||
array[pivot++] = array[size];
|
||||
return pivot;
|
||||
}
|
||||
|
||||
void printArray(int *array, int size) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", array[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
int value, index, size, buffer, *array;
|
||||
|
||||
printf("This program tests the functionality of functions to insert and "
|
||||
"remove content of an array. Type in a sequence of numbers ended "
|
||||
"with \".\" and press enter: ");
|
||||
array = readInput(&size, &buffer);
|
||||
|
||||
printf("Select an index to insert a value: ");
|
||||
scanf(" %d", &index);
|
||||
printf("Select a value to be inserted: ");
|
||||
scanf(" %d", &value);
|
||||
array = insert(value, index, array, &size, &buffer);
|
||||
printf("Resulting array: ");
|
||||
printArray(array, size);
|
||||
|
||||
printf("Select an index to remove a value: ");
|
||||
scanf(" %d", &index);
|
||||
printf("Value removed: %d\nResulting array:", pop(&array, index, &size));
|
||||
printArray(array, size);
|
||||
|
||||
size = removeZeroes(array, size);
|
||||
printf("With all null elements removed, the resulting array is:\n");
|
||||
printArray(array, size);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int countZeroes(long number, int currentCount) {
|
||||
if (number == 0)
|
||||
return currentCount;
|
||||
return countZeroes(number / 10, currentCount) + ((number % 10) ? 0 : 1);
|
||||
}
|
||||
|
||||
void printMostZeroes(long max, int maxCount) {
|
||||
long current;
|
||||
int currentCount = 0;
|
||||
|
||||
if (!scanf(" %ld", ¤t)) {
|
||||
if (!maxCount)
|
||||
printf("There are no numbers containing zeroes in the sequence "
|
||||
"provided.\n");
|
||||
else
|
||||
printf(
|
||||
"The number with the longest sequence of zeroes is %ld, with "
|
||||
"%d zeroes in total.\n",
|
||||
max, maxCount);
|
||||
return;
|
||||
}
|
||||
|
||||
currentCount = (!current) ? 1 : countZeroes(current, currentCount);
|
||||
if (currentCount > maxCount)
|
||||
printMostZeroes(current, currentCount);
|
||||
else
|
||||
printMostZeroes(max, maxCount);
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("This program counts the number of following zeroes in an array of "
|
||||
"numbers and yields a number with the greatest number of them. "
|
||||
"Type in a series of numbers ended with '.' and press ENTER:\n");
|
||||
printMostZeroes(0, 0);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char *resizeString(char *string, int *size) {
|
||||
*size *= 2;
|
||||
return realloc(string, *size * sizeof(char));
|
||||
}
|
||||
|
||||
char *readInput(int *size) {
|
||||
char c, *string = malloc(sizeof(char));
|
||||
int i;
|
||||
*size = 1;
|
||||
|
||||
for (i = 0; (c = getchar()) != '\n' || c == EOF; string[i++] = c)
|
||||
if (i == *size - 1)
|
||||
string = resizeString(string, size);
|
||||
string[i++] = '\0';
|
||||
*size = i;
|
||||
return string;
|
||||
}
|
||||
|
||||
int recursiveDeleteCharacter(char *string, char c, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
pivot = recursiveDeleteCharacter(string, c, --size);
|
||||
if (string[size] != c)
|
||||
string[pivot++] = string[size];
|
||||
return pivot;
|
||||
}
|
||||
|
||||
int deleteCharacters(char *string, int size, char *chars) {
|
||||
int i;
|
||||
|
||||
for (i = 0; chars[i] != '\0'; i++)
|
||||
size = recursiveDeleteCharacter(string, chars[i], size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void deleteCharacter(char *string, char c) {
|
||||
int i, j;
|
||||
|
||||
for (i = j = 0; string[j] != '\0'; j++)
|
||||
if (string[j] != c)
|
||||
string[i++] = string[j];
|
||||
string[i] = string[j];
|
||||
}
|
||||
|
||||
int main() {
|
||||
char *string;
|
||||
int stringSize, charQuantity;
|
||||
|
||||
printf("This program deletes given characters from a given string. Type "
|
||||
"in a string and press ENTER:\n");
|
||||
string = readInput(&stringSize);
|
||||
|
||||
printf("Type in characters to be deleted: ");
|
||||
stringSize = deleteCharacters(string, stringSize, readInput(&charQuantity));
|
||||
printf("This is the resulting string:\n%s\n", string);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int value;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
typedef struct {
|
||||
Node *start;
|
||||
} List;
|
||||
|
||||
Node *newNode(int value, Node *next) {
|
||||
Node *n = malloc(sizeof(Node));
|
||||
|
||||
n->value = value;
|
||||
n->next = next;
|
||||
return n;
|
||||
}
|
||||
|
||||
Node *freeNode(Node *n) {
|
||||
Node *next = n->next;
|
||||
free(n);
|
||||
return next;
|
||||
}
|
||||
|
||||
void freeAllNodes(Node *n) {
|
||||
if (!n)
|
||||
return;
|
||||
freeAllNodes(n->next);
|
||||
free(n);
|
||||
}
|
||||
|
||||
List *newList() {
|
||||
List *l = malloc(sizeof(List));
|
||||
|
||||
l->start = NULL;
|
||||
return l;
|
||||
}
|
||||
|
||||
void freeList(List *l) {
|
||||
freeAllNodes(l->start);
|
||||
free(l);
|
||||
}
|
||||
|
||||
bool push(Node *n, int value) {
|
||||
if (n->value == value)
|
||||
return false;
|
||||
if (!n->next || n->next->value > value) {
|
||||
n->next = newNode(value, n->next);
|
||||
return true;
|
||||
}
|
||||
return push(n->next, value);
|
||||
}
|
||||
|
||||
Node *pull(Node *n, int value, bool *found) {
|
||||
if (n) {
|
||||
if (n->value == value) {
|
||||
*found = true;
|
||||
return freeNode(n);
|
||||
}
|
||||
if (n->value < value)
|
||||
n->next = pull(n->next, value, found);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
bool insert(List *l, int value) {
|
||||
if (!l)
|
||||
return false;
|
||||
if (!l->start || l->start->value > value) {
|
||||
l->start = newNode(value, l->start);
|
||||
return true;
|
||||
}
|
||||
return push(l->start, value);
|
||||
}
|
||||
|
||||
bool take(List *l, int value) {
|
||||
bool found = false;
|
||||
if (l)
|
||||
l->start = pull(l->start, value, &found);
|
||||
return found;
|
||||
}
|
||||
|
||||
void printNodes(Node *n) {
|
||||
if (!n)
|
||||
printf("\n");
|
||||
else {
|
||||
printf("%d ", n->value);
|
||||
printNodes(n->next);
|
||||
}
|
||||
}
|
||||
|
||||
void printList(List *l) {
|
||||
printf("List contents: ");
|
||||
printNodes(l->start);
|
||||
}
|
||||
|
||||
void readCommands() {
|
||||
char option;
|
||||
int value;
|
||||
List *l = newList();
|
||||
|
||||
while (scanf(" %[ir]", &option)) {
|
||||
if (option == 'i') {
|
||||
while (scanf(" %d", &value))
|
||||
if (!insert(l, value))
|
||||
printf(
|
||||
"Value %d already present in the list, ignoring...\n",
|
||||
value);
|
||||
} else
|
||||
while (scanf(" %d", &value))
|
||||
if (!take(l, value))
|
||||
printf("Value %d not present in the list, ignoring...\n",
|
||||
value);
|
||||
printList(l);
|
||||
}
|
||||
printf("Terminating execution...\n");
|
||||
freeList(l);
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("This program stores unique integer values in an ordered linked "
|
||||
"list. Let n be an integer or a set of integers separated by "
|
||||
"spaces, type i n to insert it in the list, r n to remove it from "
|
||||
"it, or type in any other character to stop the execution of the "
|
||||
"program. Don't forget to press ENTER after passing a command.\n");
|
||||
readCommands();
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define LENGTH 10
|
||||
|
||||
int *readNumbers(int size) {
|
||||
int i = 0, value, *v = calloc(size, sizeof(int));
|
||||
|
||||
while (i < size && scanf(" %d", &value)) {
|
||||
if (value > 9 || value < 0) {
|
||||
printf("Value %d out of range: ignoring...\n", value);
|
||||
continue;
|
||||
}
|
||||
v[i++] = value;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void printNumbers(int *v, int size) {
|
||||
int i;
|
||||
|
||||
printf("Array contents: ");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", v[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int *permutate(int *v, int size) {
|
||||
int i, *w = calloc(size, sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
w[v[i]] = i;
|
||||
return w;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int *v;
|
||||
printf("This program takes integers from 0 through 9 and stores it in an "
|
||||
"array v of length 10. Later, it swaps the number positions in such "
|
||||
"a way that for each v[i] = j there will be a v[j] = i after the "
|
||||
"numbers are swapped. Positions left unspecified will be set to "
|
||||
"0.\nType in a sequence of 10 numbers:\n");
|
||||
printNumbers(v = readNumbers(LENGTH), LENGTH);
|
||||
printf("Permutation.\n");
|
||||
printNumbers(permutate(v, LENGTH), LENGTH);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void swap(int *a, int *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
int partition(int *array, int pivot, int size) {
|
||||
int i, j;
|
||||
|
||||
swap(array + pivot, array + --size);
|
||||
for (i = j = 0; i < size; i++)
|
||||
if (array[i] <= array[size])
|
||||
swap(array + i, array + j++);
|
||||
swap(array + i, array + j);
|
||||
return j;
|
||||
}
|
||||
|
||||
int quickSelect(int *array, int size, int i) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return *array;
|
||||
pivot = partition(array, i, size);
|
||||
if (pivot == i)
|
||||
return array[i];
|
||||
if (i < pivot)
|
||||
return quickSelect(array, size, i);
|
||||
pivot++;
|
||||
return quickSelect(array + pivot, size - pivot, i - pivot);
|
||||
}
|
||||
|
||||
int *createArray(int size) {
|
||||
int i, *array = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
array[i] = rand();
|
||||
return array;
|
||||
}
|
||||
|
||||
int max(int *array, int size) {
|
||||
int m;
|
||||
|
||||
if (!size)
|
||||
return INT_MIN;
|
||||
m = max(array + 1, size - 1);
|
||||
return (m > *array) ? m : *array;
|
||||
}
|
||||
|
||||
void printArray(int *array, int size) {
|
||||
int i;
|
||||
|
||||
printf("Array's contents: ");
|
||||
for (i = 0; i < size; i++)
|
||||
printf(" %d", array[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
int *array, size;
|
||||
printf("This program evaluates the correctness of a function to get the "
|
||||
"maximum value in an array by using another function that is much "
|
||||
"more complex and prone to error in its implementation (albeit it "
|
||||
"executes much faster): the quick select. Let's see how that "
|
||||
"goes.\n\nFirst we generate an array containing randomly generated "
|
||||
"values. Choose a size for that array: ");
|
||||
scanf(" %d", &size);
|
||||
if (size < 0) {
|
||||
printf("Invalid size.\n");
|
||||
return 1;
|
||||
}
|
||||
array = createArray(size);
|
||||
printArray(array, size);
|
||||
printf("The maximum function indicates the maximum value is: %d\n",
|
||||
max(array, size));
|
||||
printf("While the quick select says it is: %d\n",
|
||||
quickSelect(array, size, size - 1));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int mdc(int a, int b) {
|
||||
int r = a % b;
|
||||
return r ? mdc(b, r) : b;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("%d\n", mdc(atoi(argv[1]), atoi(argv[2])));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void printNext(int a, int b, int n) {
|
||||
if (n <= 0)
|
||||
return;
|
||||
printf("%d ", b);
|
||||
printNext(b, a + b, n - 1);
|
||||
}
|
||||
|
||||
void fibonacci(int n) {
|
||||
printf("Sequência Fibonacci até o %dº elemento: 0 ", n);
|
||||
printNext(0, 1, n - 1);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
|
||||
printf("Este programa calcula os valores até o enésimo número na sequência "
|
||||
"Fibonacci.\nDigite um valor inteiro n tal que n < 47: ");
|
||||
if (!scanf(" %d", &n) || n < 0 || n > 47) {
|
||||
printf("Valor inválido.\n");
|
||||
return 1;
|
||||
}
|
||||
fibonacci(n);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int value;
|
||||
struct node *next;
|
||||
} List;
|
||||
|
||||
List *newList(int value, List *next) {
|
||||
List *l = malloc(sizeof(List));
|
||||
|
||||
l->value = value;
|
||||
l->next = next;
|
||||
return l;
|
||||
}
|
||||
|
||||
void freeList(List *l) {
|
||||
if (!l)
|
||||
return;
|
||||
freeList(l->next);
|
||||
free(l);
|
||||
}
|
||||
|
||||
List *freeNode(List *l) {
|
||||
List *next = l->next;
|
||||
free(l);
|
||||
return next;
|
||||
}
|
||||
|
||||
bool listCmp(List *l1, List *l2) {
|
||||
if (l1 == l2)
|
||||
return true;
|
||||
if (!(l1 && l2) || !listCmp(l1->next, l2->next))
|
||||
return false;
|
||||
return (l1->value == l2->value);
|
||||
}
|
||||
|
||||
List *listCopy(List *l) { return l ? newList(l->value, listCopy(l->next)) : l; }
|
||||
|
||||
List *invert(List *current) {
|
||||
List *prev = NULL, *next;
|
||||
|
||||
while (current) {
|
||||
next = current->next;
|
||||
current->next = prev;
|
||||
prev = current;
|
||||
current = next;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
List *swap(List *prev, List *current) {
|
||||
List *HEAD;
|
||||
|
||||
if (!current)
|
||||
return prev;
|
||||
HEAD = swap(current, current->next);
|
||||
current->next = prev;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
List *recInvert(List *l) { return swap(NULL, l); }
|
||||
|
||||
List *recListCat(List *l1, List *l2) {
|
||||
if (!l1)
|
||||
return l2;
|
||||
l1->next = recListCat(l1->next, l2);
|
||||
return l1;
|
||||
}
|
||||
|
||||
void listCat(List *l1, List *l2) {
|
||||
if (!l1)
|
||||
l1 = l2;
|
||||
else {
|
||||
while (l1->next)
|
||||
l1 = l1->next;
|
||||
l1->next = l2;
|
||||
}
|
||||
}
|
||||
|
||||
bool isCrescent(List *l) {
|
||||
if (!l->next)
|
||||
return true;
|
||||
return (l->value <= l->next->value) ? isCrescent(l->next) : false;
|
||||
}
|
||||
|
||||
List *minimum(List *l) {
|
||||
List *min;
|
||||
|
||||
if (!l->next)
|
||||
return l;
|
||||
min = minimum(l->next);
|
||||
return (l->value <= min->value) ? l : min;
|
||||
}
|
||||
|
||||
List *middle(List *l) {
|
||||
List *slow, *fast;
|
||||
slow = fast = l;
|
||||
|
||||
while (fast) {
|
||||
fast = fast->next;
|
||||
if (!fast)
|
||||
break;
|
||||
fast = fast->next;
|
||||
slow = slow->next;
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
|
||||
List *push(List *l, int value) {
|
||||
if (!l)
|
||||
l = newList(value, l);
|
||||
else
|
||||
l->next = push(l->next, value);
|
||||
return l;
|
||||
}
|
||||
|
||||
List *pull(List *l, int value) {
|
||||
if (l) {
|
||||
if (l->value == value)
|
||||
return freeNode(l);
|
||||
l->next = pull(l->next, value);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
List *pullAll(List *l, int value) {
|
||||
if (l) {
|
||||
if (l->value == value)
|
||||
return pullAll(freeNode(l), value);
|
||||
l->next = pullAll(l->next, value);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void flushInput() {
|
||||
int c;
|
||||
if ((c = getchar()) != '\n' && c != EOF)
|
||||
flushInput();
|
||||
}
|
||||
|
||||
List *readList() {
|
||||
int value;
|
||||
char c;
|
||||
if (scanf("%d%c", &value, &c))
|
||||
return newList(value, (c == '\n') ? NULL : readList());
|
||||
flushInput();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
List *insertAfter(List *l, int value, int n) {
|
||||
List *prev;
|
||||
|
||||
if (!l || n <= 0)
|
||||
return newList(value, l);
|
||||
for (prev = l; prev->next && n > 0; n--)
|
||||
prev = prev->next;
|
||||
prev->next = newList(value, prev->next);
|
||||
return l;
|
||||
}
|
||||
|
||||
List *recInsertAfter(List *l, int value, int n) {
|
||||
if (!l || n <= 0)
|
||||
return newList(value, l);
|
||||
l->next = insertAfter(l->next, value, n - 1);
|
||||
return l;
|
||||
}
|
||||
|
||||
List *exchange(List *prev, List *next) {
|
||||
List *tmp = prev->next;
|
||||
prev->next = next->next->next;
|
||||
next->next->next = tmp;
|
||||
tmp = next->next;
|
||||
next->next = prev;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
List *findPair(List *prev, List *next, int offset) {
|
||||
if (offset > 1)
|
||||
return findPair(prev, next->next, offset - 1);
|
||||
return (offset == 1) ? exchange(prev, next) : prev;
|
||||
}
|
||||
|
||||
List *moveByIndex(List *l, int index, int offset) {
|
||||
if (l) {
|
||||
if (index < 1)
|
||||
return findPair(l, l, offset);
|
||||
l->next = moveByIndex(l->next, index - 1, offset);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void printList(List *l) {
|
||||
if (!l)
|
||||
printf("\n");
|
||||
else {
|
||||
printf("%d ", l->value);
|
||||
printList(l->next);
|
||||
}
|
||||
}
|
||||
|
||||
void listInfo(List *l) {
|
||||
printf("List's contents: ");
|
||||
printList(l);
|
||||
printf("Is crescent: %s; Minimum value: %d; Middle value: %d.\n",
|
||||
isCrescent(l) ? "Yes" : "No", minimum(l)->value, middle(l)->value);
|
||||
}
|
||||
|
||||
int main() {
|
||||
List *l1, *l2, *l3;
|
||||
l1 = l2 = NULL;
|
||||
int i1, i2;
|
||||
|
||||
printf("This program reads a couple of linked lists and compares them. For "
|
||||
"the first linked list, type in a sequence of numbers to store and "
|
||||
"press ENTER:\n");
|
||||
listInfo(l1 = readList());
|
||||
printf("Now for the contents of the second list:\n");
|
||||
listInfo(l2 = readList());
|
||||
printf("Is list 1 equal to list 1: %s; is list 1 equal to list 2: %s\n",
|
||||
listCmp(l1, l1) ? "Yes" : "No", listCmp(l1, l2) ? "Yes" : "No");
|
||||
printf("This list is a copy of the first list:");
|
||||
printList(l3 = listCopy(l1));
|
||||
printf(
|
||||
"As it can be seen in their different addresses: l1 -> %p; l3 -> %p\n",
|
||||
l1, l3);
|
||||
printf("This is a concatenation of lists 1 and 2:");
|
||||
listCat(l1, l2);
|
||||
printList(l1);
|
||||
l1 = recInvert(l1);
|
||||
printf("This the list inverted by a recursive function: ");
|
||||
printList(l1);
|
||||
printf("And inverted again by a iteractive function: ");
|
||||
printList(l1 = invert(l1));
|
||||
printf("Type a value to be inserted to that array and an index in which to "
|
||||
"put it: ");
|
||||
scanf(" %d %d", &i1, &i2);
|
||||
flushInput();
|
||||
l1 = recInsertAfter(l1, i1, i2);
|
||||
printf("Resulting linked list: ");
|
||||
printList(l1);
|
||||
printf("Again, to test the iteractive version: ");
|
||||
scanf(" %d %d", &i1, &i2);
|
||||
flushInput();
|
||||
l1 = insertAfter(l1, i1, i2);
|
||||
printf("Resulting linked list: ");
|
||||
printList(l1);
|
||||
printf("Now a function to change the position of two values based on their "
|
||||
"indexes. Choose to indexes to have their values swapped: ");
|
||||
scanf(" %d %d", &i1, &i2);
|
||||
l1 = moveByIndex(l1, i1, i2);
|
||||
printList(l1);
|
||||
printf("Test removing the first occurence of a value: ");
|
||||
scanf(" %d", &i1);
|
||||
l1 = pull(l1, i1);
|
||||
printList(l1);
|
||||
printf("Now test removing all occurences: ");
|
||||
scanf(" %d", &i1);
|
||||
l1 = pullAll(l1, i1);
|
||||
printList(l1);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct node {
|
||||
char *string;
|
||||
int length, count;
|
||||
struct node *next;
|
||||
} List;
|
||||
|
||||
List *addWord(char *string, List *next) {
|
||||
List *l = malloc(sizeof(List));
|
||||
l->length = strlen(string);
|
||||
l->string = malloc((l->length + 1) * sizeof(char));
|
||||
|
||||
strcpy(l->string, string);
|
||||
l->count = 1;
|
||||
l->next = next;
|
||||
return l;
|
||||
}
|
||||
|
||||
void freeList(List *l) {
|
||||
if (!l)
|
||||
return;
|
||||
freeList(l->next);
|
||||
free(l->string);
|
||||
free(l);
|
||||
}
|
||||
|
||||
List *push(List *l, char *string) {
|
||||
int order;
|
||||
|
||||
if (!l || (order = strcmp(string, l->string)) < 0)
|
||||
return addWord(string, l);
|
||||
if (order > 0)
|
||||
l->next = push(l->next, string);
|
||||
else
|
||||
l->count++;
|
||||
return l;
|
||||
}
|
||||
|
||||
void printList(List *l) {
|
||||
if (l) {
|
||||
if (l->length > 35)
|
||||
printf("%-36.36s... %d\n", l->string, l->count);
|
||||
else
|
||||
printf("%-40.40s%d\n", l->string, l->count);
|
||||
printList(l->next);
|
||||
}
|
||||
}
|
||||
|
||||
List *readFile(FILE *f, List *l) {
|
||||
char string[64];
|
||||
while (fscanf(f, " %s", string) != EOF)
|
||||
l = push(l, string);
|
||||
return l;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
List *l = NULL;
|
||||
FILE *f = fopen(argv[1], "r");
|
||||
if (!f)
|
||||
return 1;
|
||||
l = readFile(f, l);
|
||||
fclose(f);
|
||||
printList(l);
|
||||
freeList(l);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int value;
|
||||
struct node *next;
|
||||
} List;
|
||||
|
||||
List *newList(int value, List *next) {
|
||||
List *l = malloc(sizeof(List));
|
||||
|
||||
l->value = value;
|
||||
l->next = next;
|
||||
return l;
|
||||
}
|
||||
|
||||
void freeList(List *l) {
|
||||
if (!l)
|
||||
return;
|
||||
freeList(l->next);
|
||||
free(l);
|
||||
}
|
||||
|
||||
List *freeNode(List *l) {
|
||||
List *next = l->next;
|
||||
free(l);
|
||||
return next;
|
||||
}
|
||||
|
||||
List *push(List *l, int value) {
|
||||
if (!l || l->value > value)
|
||||
return newList(value, l);
|
||||
if (l->value < value)
|
||||
l->next = push(l->next, value);
|
||||
return l;
|
||||
}
|
||||
|
||||
List *pull(List *l, int value) {
|
||||
if (l && l->value <= value) {
|
||||
if (l->value == value)
|
||||
return freeNode(l);
|
||||
l->next = pull(l->next, value);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
List *concatenate(List *l1, List *l2) {
|
||||
if (!l1)
|
||||
return l2;
|
||||
if (!l2)
|
||||
return l1;
|
||||
if (l1->value <= l2->value) {
|
||||
l1->next = concatenate(l1->next, l2);
|
||||
return l1;
|
||||
}
|
||||
l2->next = concatenate(l1, l2->next);
|
||||
return l2;
|
||||
}
|
||||
|
||||
int length(List *l) { return l ? length(l->next) + 1 : 0; }
|
||||
|
||||
void printList(List *l) {
|
||||
if (!l)
|
||||
printf("\n");
|
||||
else {
|
||||
printf("%d ", l->value);
|
||||
printList(l->next);
|
||||
}
|
||||
}
|
||||
|
||||
void flushInput() {
|
||||
int c;
|
||||
if ((c = getchar()) != '\n' && c != EOF)
|
||||
flushInput();
|
||||
}
|
||||
|
||||
List *readList() {
|
||||
int value;
|
||||
char c;
|
||||
List *l = NULL;
|
||||
|
||||
while (scanf(" %d%c", &value, &c)) {
|
||||
l = push(l, value);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void readCommands() {
|
||||
char option, c;
|
||||
int value;
|
||||
List *l = NULL;
|
||||
|
||||
while (scanf(" %[irc\n]", &option)) {
|
||||
if (option == '\n')
|
||||
break;
|
||||
if (option == 'i')
|
||||
l = readList();
|
||||
else if (option == 'r')
|
||||
while (scanf("%d%c", &value, &c) && c != '\n')
|
||||
l = pull(l, value);
|
||||
else
|
||||
l = concatenate(l, readList());
|
||||
printf("Resulting list: ");
|
||||
printList(l);
|
||||
printf("List length: %d\n", length(l));
|
||||
}
|
||||
printf("Terminating execution...\n");
|
||||
freeList(l);
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf(
|
||||
"This program stores unique integer values in an ordered linked "
|
||||
"list. Let n be an integer or a set of integers separated by "
|
||||
"spaces:\nType i n to insert it in the list;\nType r n to remove it "
|
||||
"from it;\nType c to concatenate it with another set of following "
|
||||
"integers;\n, or type in any other character to stop the execution of "
|
||||
"the program. Don't forget to press ENTER after passing a command.\n");
|
||||
readCommands();
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int i;
|
||||
struct node *next;
|
||||
} List;
|
||||
|
||||
List *newList(int i, List *next) {
|
||||
List *l = malloc(sizeof(List));
|
||||
|
||||
l->i = i;
|
||||
l->next = next;
|
||||
return l;
|
||||
}
|
||||
|
||||
List *insert(int total, int left, List **end) {
|
||||
if (left > 0)
|
||||
return newList(total - left, insert(total, left - 1, end));
|
||||
return (*end = newList(total - left, NULL));
|
||||
}
|
||||
|
||||
List *createCircle(int n) {
|
||||
List *start, *end;
|
||||
start = insert(n, n - 1, &end);
|
||||
end->next = start;
|
||||
return start;
|
||||
}
|
||||
|
||||
List *pull(List *l) {
|
||||
List *next = l->next;
|
||||
free(l);
|
||||
return next;
|
||||
}
|
||||
|
||||
List *josephus(List *l, int interval) {
|
||||
int skip = interval;
|
||||
|
||||
while (l != l->next) {
|
||||
while (skip-- > 0)
|
||||
l = l->next;
|
||||
l->next = pull(l->next);
|
||||
skip = interval;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
List *push(List *l, int value) {
|
||||
if (!l)
|
||||
l = newList(value, l);
|
||||
else
|
||||
l->next = push(l->next, value);
|
||||
return l;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("%d\n", josephus(createCircle(atoi(argv[1])), atoi(argv[2]))->i);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define NORTH 0
|
||||
#define EAST 1
|
||||
#define SOUTH 2
|
||||
#define WEST 3
|
||||
#define SIDES 4
|
||||
|
||||
typedef struct tile {
|
||||
int x, y, g, f;
|
||||
struct tile *prev;
|
||||
char c;
|
||||
} Tile;
|
||||
|
||||
typedef struct queue {
|
||||
Tile *t;
|
||||
struct queue *next;
|
||||
} Queue;
|
||||
|
||||
typedef struct {
|
||||
int height, width;
|
||||
Tile ***tiles, *start, *end;
|
||||
} Map;
|
||||
|
||||
Tile *newTile(int x, int y, int g, char c) {
|
||||
Tile *t = malloc(sizeof(Tile));
|
||||
|
||||
t->x = x;
|
||||
t->y = y;
|
||||
t->g = g;
|
||||
t->c = c;
|
||||
return t;
|
||||
}
|
||||
|
||||
Queue *newQueue(Tile *t, Queue *next) {
|
||||
Queue *q = malloc(sizeof(Queue));
|
||||
|
||||
q->t = t;
|
||||
q->next = next;
|
||||
return q;
|
||||
}
|
||||
|
||||
Queue *freeNode(Queue *q) {
|
||||
Queue *next = q->next;
|
||||
|
||||
free(q);
|
||||
return next;
|
||||
}
|
||||
|
||||
void freeQueue(Queue *q) {
|
||||
if (!q)
|
||||
return;
|
||||
freeQueue(q->next);
|
||||
free(q);
|
||||
}
|
||||
|
||||
Tile **readTiles(FILE *f, Map *m, int row) {
|
||||
int i;
|
||||
char c;
|
||||
Tile **tiles = malloc((m->width + 2) * sizeof(Tile *));
|
||||
|
||||
tiles[0] = NULL;
|
||||
tiles++;
|
||||
for (i = 0; i < m->width; i++) {
|
||||
if ((c = getc(f)) == '#')
|
||||
tiles[i] = NULL;
|
||||
else if (c == 's') {
|
||||
m->start = tiles[i] = newTile(i, row, 0, c);
|
||||
tiles[i]->prev = NULL;
|
||||
} else {
|
||||
tiles[i] = newTile(i, row, INT_MAX, c);
|
||||
if (c == 'e')
|
||||
m->end = tiles[i];
|
||||
}
|
||||
}
|
||||
getc(f);
|
||||
tiles[i] = NULL;
|
||||
return tiles;
|
||||
}
|
||||
|
||||
Tile ***readRows(FILE *f, Map *m) {
|
||||
int i;
|
||||
Tile ***rows = malloc((m->height + 2) * sizeof(Tile **));
|
||||
rows[0] = calloc(m->width + 2, sizeof(Tile *));
|
||||
rows++;
|
||||
for (i = 0; i < m->height; i++)
|
||||
rows[i] = readTiles(f, m, i);
|
||||
rows[i] = calloc(m->width + 2, sizeof(Tile *));
|
||||
return rows;
|
||||
}
|
||||
|
||||
Map *newMap(FILE *f) {
|
||||
Map *m = malloc(sizeof(Map));
|
||||
|
||||
fscanf(f, "%d %d\n", &(m->width), &(m->height));
|
||||
m->tiles = readRows(f, m);
|
||||
return m;
|
||||
}
|
||||
|
||||
Queue *push(Queue *q, Tile *t) {
|
||||
if (!q)
|
||||
return newQueue(t, NULL);
|
||||
if (q->t != t) {
|
||||
if (q->t->f > t->f)
|
||||
return newQueue(t, q);
|
||||
q->next = push(q->next, t);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
Tile *pop(Queue **q) {
|
||||
Tile *t;
|
||||
|
||||
if (!(*q))
|
||||
return NULL;
|
||||
t = (*q)->t;
|
||||
*q = freeNode(*q);
|
||||
return t;
|
||||
}
|
||||
|
||||
Tile **listNeighbors(Map *m, Tile *t) {
|
||||
Tile **neighbors = malloc(SIDES * sizeof(Tile *));
|
||||
|
||||
neighbors[NORTH] = m->tiles[t->y - 1][t->x];
|
||||
neighbors[EAST] = m->tiles[t->y][t->x + 1];
|
||||
neighbors[SOUTH] = m->tiles[t->y + 1][t->x];
|
||||
neighbors[WEST] = m->tiles[t->y][t->x - 1];
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
int manhattan(Tile *start, Tile *end) {
|
||||
return abs(start->x - end->x) + abs(start->y + end->y);
|
||||
}
|
||||
|
||||
Tile *Astar(Map *m) {
|
||||
int i, distance;
|
||||
Queue *openSet = newQueue(m->start, NULL);
|
||||
Tile *t, **neighbors;
|
||||
|
||||
while ((t = pop(&openSet)) && t != m->end) {
|
||||
neighbors = listNeighbors(m, t);
|
||||
|
||||
for (i = 0; i < SIDES; i++) {
|
||||
if (!neighbors[i])
|
||||
continue;
|
||||
distance = t->g + 1;
|
||||
if (distance >= neighbors[i]->g)
|
||||
continue;
|
||||
neighbors[i]->prev = t;
|
||||
neighbors[i]->g = distance;
|
||||
neighbors[i]->f = distance + manhattan(neighbors[i], m->end);
|
||||
openSet = push(openSet, neighbors[i]);
|
||||
}
|
||||
free(neighbors);
|
||||
}
|
||||
freeQueue(openSet);
|
||||
return t;
|
||||
}
|
||||
|
||||
void printMap(Map *m) {
|
||||
int i, j;
|
||||
Tile *t;
|
||||
|
||||
for (i = 0; i < m->height; i++) {
|
||||
for (j = 0; j < m->width; j++) {
|
||||
t = m->tiles[i][j];
|
||||
if (t)
|
||||
printf("%c", t->c);
|
||||
else
|
||||
printf("#");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int path(Tile *end, int count) {
|
||||
if (!end->prev)
|
||||
printf("Start");
|
||||
else {
|
||||
count = path(end->prev, count + 1);
|
||||
end->c = 'O';
|
||||
if (end->prev->y > end->y)
|
||||
printf(" -> North");
|
||||
else if (end->prev->y < end->y)
|
||||
printf(" -> South");
|
||||
else if (end->prev->x < end->x)
|
||||
printf(" -> East");
|
||||
else
|
||||
printf(" -> West");
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int length = 0;
|
||||
FILE *f = fopen(argv[1], "r");
|
||||
Map *m = newMap(f);
|
||||
|
||||
fclose(f);
|
||||
if (!Astar(m)) {
|
||||
printf("There's no viable path from start to goal.\n");
|
||||
return 1;
|
||||
}
|
||||
printf("From start to goal, there's the path: ");
|
||||
length = path(m->end, length);
|
||||
printf("\n");
|
||||
m->end->c = 'e';
|
||||
printf("\nHere its representation:\n");
|
||||
printMap(m);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int value;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
typedef struct {
|
||||
Node *start, *end;
|
||||
} List;
|
||||
|
||||
List *createList() {
|
||||
List *l = malloc(sizeof(List));
|
||||
l->start = l->end = NULL;
|
||||
return l;
|
||||
}
|
||||
|
||||
bool isEmpty(List *l) { return !l->start; }
|
||||
|
||||
Node *createNode(int value) {
|
||||
Node *n = malloc(sizeof(Node));
|
||||
n->value = value;
|
||||
n->next = NULL;
|
||||
return n;
|
||||
}
|
||||
|
||||
Node *freeNode(Node *n) {
|
||||
Node *next = n->next;
|
||||
free(n);
|
||||
return next;
|
||||
}
|
||||
|
||||
void freeList(List *l) {
|
||||
Node *n = l->start;
|
||||
|
||||
while (n)
|
||||
n = freeNode(n);
|
||||
free(l);
|
||||
}
|
||||
|
||||
void insert(List *l, int value) {
|
||||
Node *new = createNode(value);
|
||||
|
||||
if (l->end)
|
||||
l->end->next = new;
|
||||
if (!l->start)
|
||||
l->start = new;
|
||||
l->end = new;
|
||||
}
|
||||
|
||||
int pull(List *l) {
|
||||
int value;
|
||||
|
||||
if (!l->start)
|
||||
return EOF;
|
||||
value = l->start->value;
|
||||
if (!(l->start = freeNode(l->start)))
|
||||
l->end = l->start;
|
||||
return value;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#include "./circArray.h"
|
||||
|
||||
bool isFull(circQueue *q) { return (q->head == (q->tail + 1) % q->size); }
|
||||
|
||||
bool isEmpty(circQueue *q) { return (q->head == q->tail); }
|
||||
|
||||
bool insert(circQueue *q, int i) {
|
||||
if (isFull(q))
|
||||
return false;
|
||||
q->array[q->tail] = i;
|
||||
q->tail = (q->tail + 1) % q->size;
|
||||
return false;
|
||||
}
|
||||
|
||||
circQueue *newQueue(int size) {
|
||||
circQueue *q = malloc(sizeof(circQueue));
|
||||
q->array = malloc(size * sizeof(int));
|
||||
|
||||
q->size = size;
|
||||
q->head = q->tail = 0;
|
||||
return q;
|
||||
}
|
||||
|
||||
int pop(circQueue *q) {
|
||||
int i;
|
||||
|
||||
if (isEmpty(q))
|
||||
return EOF;
|
||||
i = q->array[q->head];
|
||||
q->head = (q->head + 1) % q->size;
|
||||
return i;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int value;
|
||||
struct node *prev, *next;
|
||||
} List;
|
||||
|
||||
List *newNode(int value) {
|
||||
List *l = malloc(sizeof(List));
|
||||
l->value = value;
|
||||
return l;
|
||||
}
|
||||
|
||||
List *freeNode(List *l) {
|
||||
List *next = l->next;
|
||||
|
||||
if (l->next == l)
|
||||
next = NULL;
|
||||
else {
|
||||
next->prev = l->prev;
|
||||
l->prev->next = next;
|
||||
}
|
||||
free(l);
|
||||
return next;
|
||||
}
|
||||
|
||||
List *newList(int value) {
|
||||
List *l = newNode(value);
|
||||
l->prev = l->next = l;
|
||||
return l;
|
||||
}
|
||||
|
||||
void push(List *l, int value) {
|
||||
List *prev = l->prev, *new = newNode(value);
|
||||
prev->next = new;
|
||||
new->prev = prev;
|
||||
new->next = l;
|
||||
l->prev = new;
|
||||
}
|
||||
|
||||
int pull(List **l) {
|
||||
int value;
|
||||
|
||||
if (!l)
|
||||
return EOF;
|
||||
value = (*l)->prev->value;
|
||||
*l = freeNode((*l)->prev);
|
||||
return value;
|
||||
}
|
||||
|
||||
bool isEmpty(List *l) { return !l; }
|
||||
|
||||
void freeList(List **l) {
|
||||
while (*l)
|
||||
*l = freeNode(*l);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include "./circList.h"
|
||||
// Implementation of a Circular Queue with no head node;
|
||||
|
||||
CircQueue *newQueue(int value) {
|
||||
CircQueue *c = malloc(sizeof(CircQueue));
|
||||
|
||||
c->value = value;
|
||||
c->next = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
CircQueue *push(CircQueue *c, int value) {
|
||||
CircQueue *new = newQueue(value);
|
||||
|
||||
if (c) {
|
||||
new->next = c->next;
|
||||
c->next = new;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
bool isEmpty(CircQueue *c) { return c; }
|
||||
|
||||
int pull(CircQueue **c) {
|
||||
CircQueue *old;
|
||||
int value;
|
||||
|
||||
if (!*c)
|
||||
return EOF;
|
||||
|
||||
old = (*c)->next;
|
||||
value = old->value;
|
||||
if (*c == old)
|
||||
*c = NULL;
|
||||
else
|
||||
(*c)->next = old->next;
|
||||
free(old);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void freeCircQueue(CircQueue **c) {
|
||||
if (!*c)
|
||||
return;
|
||||
freeQueue(*c, *c);
|
||||
*c = NULL;
|
||||
}
|
||||
|
||||
void freeQueue(CircQueue *start, CircQueue *current) {
|
||||
CircQueue *next = current->next;
|
||||
free(current);
|
||||
|
||||
if (next != start)
|
||||
freeQueue(start, next);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int value;
|
||||
struct node *next;
|
||||
} CircList;
|
||||
|
||||
CircList *newList() {
|
||||
CircList *c = malloc(sizeof(CircList));
|
||||
c->next = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
CircList *freeNode(CircList *c) {
|
||||
CircList *next = c->next;
|
||||
free(c);
|
||||
return next;
|
||||
}
|
||||
|
||||
void freeList(CircList **c) {
|
||||
CircList *current = *c;
|
||||
|
||||
while ((current = freeNode(current)) != *c) {
|
||||
}
|
||||
*c = NULL;
|
||||
}
|
||||
|
||||
bool isEmpty(CircList *c) { return c->next == c; }
|
||||
|
||||
CircList *push(CircList *c, int value) {
|
||||
CircList *new = malloc(sizeof(CircList)), *next;
|
||||
|
||||
c->value = value;
|
||||
next = c->next;
|
||||
c->next = new;
|
||||
new->next = next;
|
||||
return new;
|
||||
}
|
||||
|
||||
int pull(CircList *c) {
|
||||
int value;
|
||||
|
||||
if (isEmpty(c))
|
||||
return EOF;
|
||||
value = c->next->value;
|
||||
c->next = freeNode(c->next);
|
||||
return value;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#include "./dynamicArray.h"
|
||||
|
||||
bool isEmpty(array *a) { return a->end == a->start; }
|
||||
|
||||
array *resize(array *a) {
|
||||
a->capacity *= 2;
|
||||
a->end -= a->start;
|
||||
a->start = 0;
|
||||
return realloc(a, a->capacity * sizeof(array));
|
||||
}
|
||||
|
||||
void insert(array *a, int i) {
|
||||
a->end++;
|
||||
if (a->end == a->capacity)
|
||||
a = resize(a);
|
||||
a->values[a->end] = i;
|
||||
}
|
||||
|
||||
int pop(array *a) { return isEmpty(a) ? EOF : a->values[a->start++]; }
|
||||
|
||||
void freeArray(array *a) {
|
||||
free(a->values);
|
||||
free(a);
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
#include "./queueArray.h"
|
||||
#include <stdio.h>
|
||||
|
||||
Queue *newQueue(int capacity) {
|
||||
Queue *q = malloc(sizeof(Queue));
|
||||
|
||||
q->array = malloc(capacity * sizeof(int));
|
||||
q->start = 0;
|
||||
q->end = -1;
|
||||
q->capacity = capacity;
|
||||
return q;
|
||||
}
|
||||
|
||||
void freeQueue(Queue *q) {
|
||||
free(q->array);
|
||||
free(q);
|
||||
}
|
||||
|
||||
Queue *resize(Queue *q) {
|
||||
q->capacity *= 2;
|
||||
return realloc(q, q->capacity * sizeof(Queue));
|
||||
}
|
||||
|
||||
int length(Queue *q) { return q->end - q->start + 1; }
|
||||
|
||||
bool isFull(Queue *q) { return length(q) == q->capacity; }
|
||||
|
||||
bool isEmpty(Queue *q) { return !length(q); }
|
||||
|
||||
void shift(Queue *q) {
|
||||
int i, offset;
|
||||
|
||||
for (i = offset = q->start; i <= q->end; i++)
|
||||
q->array[i - offset] = q->array[i];
|
||||
q->start = 0;
|
||||
q->end -= offset;
|
||||
}
|
||||
|
||||
bool insert(Queue *q, int value) {
|
||||
if (isFull(q))
|
||||
return false;
|
||||
if (q->end == q->capacity - 1)
|
||||
shift(q);
|
||||
q->array[++q->end] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
int dequeue(Queue *q) {
|
||||
int i = q->array[q->start++];
|
||||
|
||||
q->start %= q->capacity;
|
||||
return i;
|
||||
}
|
||||
|
||||
int minimum(int a, int b) { return (b > a) ? a : b; }
|
||||
|
||||
bool blocked(char **map, int height, int width, int x, int y) {
|
||||
return (x < 0 || x >= width || y < 0 || y >= height || map[x][y] == '#');
|
||||
}
|
||||
|
||||
int distance(int size, int dist[][size], int a, int b) {
|
||||
int i, min;
|
||||
|
||||
if (dist[a][b] > 0)
|
||||
return dist[a][b];
|
||||
min = size;
|
||||
for (i = 0; i < size; i++)
|
||||
if (dist[a][i] > 0)
|
||||
min = minimum(min, dist[a][i] + distance(size, dist, i, b));
|
||||
return min;
|
||||
}
|
||||
|
||||
int *distanceFrom(int size, int dist[][size], int to) {
|
||||
int from, *distFrom = malloc(size * sizeof(int));
|
||||
Queue *points = newQueue(size);
|
||||
|
||||
for (from = 0; from < size; from++)
|
||||
distFrom[from] = size;
|
||||
distFrom[to] = 0;
|
||||
insert(points, to);
|
||||
|
||||
while (!isEmpty(points)) {
|
||||
from = dequeue(points);
|
||||
for (to = 0; to < size; to++) {
|
||||
if (dist[from][to] != 1 || distFrom[to] < size)
|
||||
continue;
|
||||
distFrom[to] = distFrom[from] + 1;
|
||||
insert(points, to);
|
||||
}
|
||||
}
|
||||
return distFrom;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i, dist[6][6] = {{0, 1, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0},
|
||||
{0, 0, 0, 0, 1, 0}, {0, 0, 1, 0, 1, 0},
|
||||
{1, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0}};
|
||||
int *distFrom = distanceFrom(6, dist, 3);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
printf("%d ", distFrom[i]);
|
||||
printf("\n");
|
||||
printf("%d\n", distance(6, dist, 3, 0));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct node {
|
||||
char c;
|
||||
struct node *prev;
|
||||
} Stack;
|
||||
|
||||
Stack *push(Stack *prev, char c) {
|
||||
Stack *new = malloc(sizeof(Stack));
|
||||
new->c = c;
|
||||
new->prev = prev;
|
||||
return new;
|
||||
}
|
||||
|
||||
Stack *freeNode(Stack *s) {
|
||||
Stack *prev = s->prev;
|
||||
free(s);
|
||||
return prev;
|
||||
}
|
||||
|
||||
void freeStack(Stack *s) {
|
||||
Stack *prev;
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
prev = s->prev;
|
||||
free(s);
|
||||
freeStack(prev);
|
||||
}
|
||||
|
||||
char pop(Stack **s) {
|
||||
char c;
|
||||
|
||||
if (!*s)
|
||||
return '\0' c = (*s)->c;
|
||||
*s = freeNode(*s);
|
||||
return c;
|
||||
}
|
||||
|
||||
char *infix2postfix(char *infix) {
|
||||
int n = strlen(infix);
|
||||
char *postfix = malloc((n + 1) * sizeof(char)), x;
|
||||
Stack *s = NULL;
|
||||
|
||||
push(s, infix[0]);
|
||||
|
||||
int j = 0;
|
||||
for (int i = 1; infix[i] != '\0'; i++) {
|
||||
switch (infix[i]) {
|
||||
case '(':
|
||||
push('(');
|
||||
break;
|
||||
case ')':
|
||||
x = pop(&s);
|
||||
while (x != '(')
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void invertWord(char *c) {
|
||||
if (!*c)
|
||||
return;
|
||||
invertWord(c + 1);
|
||||
printf("%c", *c);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
invertWord(argv[i]);
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// The following functions takes a stack of characters as an argument and
|
||||
// removes from it all trailing 'A's before inserting a 'B' into it.
|
||||
|
||||
void Sledgewick(Stack *s) {
|
||||
while (!isEmpty(s) && peek(s) == 'A')
|
||||
pull(s);
|
||||
push(s, 'B');
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
char *c;
|
||||
int top, size;
|
||||
} Stack;
|
||||
|
||||
Stack *newStack(int size) {
|
||||
Stack *s = malloc(sizeof(Stack));
|
||||
|
||||
s->c = malloc(size * sizeof(char));
|
||||
s->size = size;
|
||||
s->top = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
bool isFull(Stack *s) { return s->top == s->size; }
|
||||
|
||||
bool isEmpty(Stack *s) { return !s->top; }
|
||||
|
||||
void resize(Stack *s) {
|
||||
s->size *= 2;
|
||||
s->c = realloc(s->c, s->size * sizeof(char));
|
||||
}
|
||||
|
||||
void push(Stack *s, char c) {
|
||||
if (isFull(s))
|
||||
resize(s);
|
||||
s->c[(s->top)++] = c;
|
||||
}
|
||||
|
||||
char pop(Stack *s) { return (isEmpty(s)) ? '\0' : s->c[--(s->top)]; }
|
|
@ -0,0 +1,60 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct node {
|
||||
char c;
|
||||
struct node *prev;
|
||||
} Stack;
|
||||
|
||||
Stack *push(Stack *prev, char c) {
|
||||
Stack *new = malloc(sizeof(Stack));
|
||||
new->c = c;
|
||||
new->prev = prev;
|
||||
return new;
|
||||
}
|
||||
|
||||
Stack *freeNode(Stack *s) {
|
||||
Stack *prev = s->prev;
|
||||
free(s);
|
||||
return prev;
|
||||
}
|
||||
|
||||
void freeStack(Stack *s) {
|
||||
Stack *prev;
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
prev = s->prev;
|
||||
free(s);
|
||||
freeStack(prev);
|
||||
}
|
||||
|
||||
bool close(Stack **s, char c) {
|
||||
if (!*s || (c == '}' && (*s)->c != '{') || (c == ']' && (*s)->c != '[') ||
|
||||
(c == ')' && (*s)->c != '('))
|
||||
return false;
|
||||
*s = freeNode(*s);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wellFormed(Stack *s, char *string) {
|
||||
if (!*string)
|
||||
return !s;
|
||||
if (strchr("([{", *string))
|
||||
s = push(s, *string);
|
||||
else if (strchr("}])", *string) && !close(&s, *string))
|
||||
return false;
|
||||
return wellFormed(s, string + 1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
Stack *s = NULL;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
if (!wellFormed(s, argv[i]))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Return an index x from an array a such that for a given value v the following
|
||||
// condition is satisfied: a[x - 1] < v ≤ a[x]. As such, if we consider *(array
|
||||
// + size) = ∞ (or INT_MAX for that matter) and *(array - 1) = -∞ (or INT_MIN)
|
||||
// it is true for each interaction of this function that *array < value ≤
|
||||
// *(array + size).
|
||||
|
||||
int binarySearch(int value, int *array, int size) {
|
||||
int index;
|
||||
|
||||
if (size <= 0)
|
||||
return 0;
|
||||
index = size / 2;
|
||||
if (array[index] >= value)
|
||||
return binarySearch(value, array, index);
|
||||
index++;
|
||||
return index + binarySearch(value, array + index, size - index);
|
||||
}
|
||||
|
||||
int *char2int(char *args[], int size) {
|
||||
int i, *array = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
array[i] = atoi(args[i + 2]);
|
||||
return array;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int size = argc - 2;
|
||||
printf("Index: %d\n",
|
||||
binarySearch(atoi(argv[1]), char2int(argv, size), size));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#include <malloc.h>
|
||||
|
||||
typedef struct {
|
||||
int low, high;
|
||||
} Interval;
|
||||
|
||||
Interval *newInterval(int low, int high) {
|
||||
Interval *i = malloc(sizeof(Interval));
|
||||
i->low = low;
|
||||
i->high = high;
|
||||
return i;
|
||||
}
|
||||
|
||||
int binarySearch(int value, Interval **i, int size) {
|
||||
int index;
|
||||
|
||||
if (size <= 0)
|
||||
return 0;
|
||||
index = size / 2;
|
||||
if (i[index]->low >= value)
|
||||
return binarySearch(value, i, index);
|
||||
index++;
|
||||
return index + binarySearch(value, i, size - index);
|
||||
}
|
||||
|
||||
Interval *searchInterval(int value, Interval **i, int size) {
|
||||
int index = binarySearch(value, i, size);
|
||||
Interval *result = i[index];
|
||||
|
||||
if (index >= size || value <= result->low || value >= result->high)
|
||||
return NULL;
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int indexIsValue(int *array, int size) {
|
||||
int first = 0, pivot = size / 2;
|
||||
|
||||
while (first < size) {
|
||||
if (array[pivot] == pivot)
|
||||
return pivot;
|
||||
if (array[pivot] < pivot)
|
||||
first = pivot + 1;
|
||||
else
|
||||
size = pivot;
|
||||
pivot = first + (size - first) / 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int *char2int(char *args[], int size) {
|
||||
int i, *array = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
array[i] = atoi(args[i + 1]);
|
||||
return array;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int size = argc - 1, *array = char2int(argv, size);
|
||||
printf("%d\n", indexIsValue(array, size));
|
||||
free(array);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int binarySearch(char *string, char **array, int size) {
|
||||
int index;
|
||||
|
||||
if (size <= 0)
|
||||
return 0;
|
||||
index = size / 2;
|
||||
if (strcmp(string, array[index]) <= 0)
|
||||
return binarySearch(string, array, index);
|
||||
index++;
|
||||
return index + binarySearch(string, array + index, size - index);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int power(int base, int exp) {
|
||||
int sqrt;
|
||||
|
||||
if (exp == 0)
|
||||
return 1;
|
||||
if (exp == 1)
|
||||
return base;
|
||||
sqrt = power(base, exp / 2);
|
||||
return sqrt * sqrt * (exp % 2 ? base : 1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("%d\n", power(atoi(argv[1]), atoi(argv[2])));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
typedef struct {
|
||||
int nUSP;
|
||||
char *name;
|
||||
} Student;
|
||||
|
||||
int binarySearch(int nUSP, Student **s, int size) {
|
||||
int index;
|
||||
|
||||
if (size <= 0)
|
||||
return 0;
|
||||
index = size / 2;
|
||||
if (s[index]->nUSP >= nUSP)
|
||||
return binarySearch(nUSP, s, index);
|
||||
index++;
|
||||
return index + binarySearch(nUSP, s + index, size - index);
|
||||
}
|
||||
|
||||
char *searchStudent(int nUSP, Student **s, int size) {
|
||||
int i = binarySearch(nUSP, s, size);
|
||||
return (i < size && s[i]->nUSP == nUSP) ? s[i]->name : "";
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int binarySearch(int value, int *array, int size) {
|
||||
int index;
|
||||
|
||||
if (size <= 0)
|
||||
return 0;
|
||||
index = size / 2;
|
||||
if (array[index] >= value)
|
||||
return binarySearch(value, array, index);
|
||||
index++;
|
||||
return index + binarySearch(value, array + index, size - index);
|
||||
}
|
||||
|
||||
void twoSum(int sum, int *array, int size) {
|
||||
int i, j;
|
||||
int last = binarySearch(sum, array, size);
|
||||
int mid = binarySearch(sum / 2, array, last);
|
||||
if (last == size)
|
||||
last--;
|
||||
for (i = ++mid; i <= last; i++) {
|
||||
j = binarySearch(sum - array[i], array, mid);
|
||||
mid = j + 1;
|
||||
if (array[j] + array[i] == sum)
|
||||
printf("%d + %d = %d\n", array[j], array[i], sum);
|
||||
}
|
||||
}
|
||||
|
||||
int *char2int(char *args[], int size) {
|
||||
int i, *array = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
array[i] = atoi(args[i + 2]);
|
||||
return array;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int size = argc - 2, *array = char2int(argv, size);
|
||||
|
||||
twoSum(atoi(argv[1]), array, size);
|
||||
free(array);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int binarySearch(int value, int *array, int size) {
|
||||
int index;
|
||||
|
||||
if (size <= 0)
|
||||
return 0;
|
||||
index = size / 2;
|
||||
if (array[index] >= value)
|
||||
return binarySearch(value, array, index);
|
||||
index++;
|
||||
return index + binarySearch(value, array + index, size - index);
|
||||
}
|
||||
|
||||
void twoSum(int sum, int *array, int size) {
|
||||
int pivot, first, last = binarySearch(sum, array, size);
|
||||
if (last == size)
|
||||
last--;
|
||||
pivot = first = 0;
|
||||
|
||||
while (first < last) {
|
||||
if (array[first] + array[last] == sum)
|
||||
printf("%d + %d = %d\n", array[first++], array[last--], sum);
|
||||
else if (pivot == first) {
|
||||
first +=
|
||||
binarySearch(sum - array[last], array + first, last - first);
|
||||
pivot = last;
|
||||
} else {
|
||||
last = first + binarySearch(sum - array[first], array + first,
|
||||
last - first);
|
||||
pivot = first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int *char2int(char *args[], int size) {
|
||||
int i, *array = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
array[i] = atoi(args[i + 2]);
|
||||
return array;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int size = argc - 2, *array = char2int(argv, size);
|
||||
|
||||
twoSum(atoi(argv[1]), array, size);
|
||||
free(array);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
# Ordenação: algoritmos elementares
|
||||
|
||||
> Resolução dos exercícios propostos
|
||||
|
||||
## Exercícios 1
|
||||
|
||||
**1.** Vide arquivo `isSorted.c` nesta pasta.
|
||||
|
||||
**2.** O algoritmo proposto, descrito abaixo, é adequado a verificação da ordenação crescente.
|
||||
|
||||
```c
|
||||
int verifica (int v[], int n) {
|
||||
if (n > 1)
|
||||
for (int i = 1; i < n; i++)
|
||||
if (v[i-1] > v[i]) return 0;
|
||||
return 1; }
|
||||
```
|
||||
|
||||
- Caso base: um ou nenhum elemento. Um arranjo nestas condições está trivialmente ordenado em ordem crescente, não há necessidade que comparações de valores sejam feitas. O algoritmo verifica se este é o caso na linha 2 e, este sendo, pula as comparações e retorna verdadeiro (1) na linha 5.
|
||||
|
||||
- Para $n > 1$: A repetição descrita na linha 3 faz com que na linha três cada valor do arranjo do segundo ao último seja comparado ao seu antecessor imediato, interrompendo a verificação e retornando falso (0) assim que um antecessor de maior valor é encontrado. Doutra forma o algoritmo procede e retorna verdadeiro na linha 5.
|
||||
|
||||
**3.** O algoritmo proposto, descrito abaixo, é inadequado a verificação da ordenação crescente.
|
||||
|
||||
```
|
||||
int verifica (int v[], int n) {
|
||||
int sim;
|
||||
for (int i = 1; i < n; i++)
|
||||
if (v[i-1] <= v[i]) sim = 1;
|
||||
else {
|
||||
sim = 0;
|
||||
break; }
|
||||
return sim; }
|
||||
```
|
||||
|
||||
No caso base $n >= 1$, o que faz com que a repetição com a verificação nunca ocorra. Ora, mas apenas pela verificação a variável `sim` é designada um valor (1) verdadeiro ou (0) falso. Assim, ao executar este algoritmo com um arranjo trivialmente ordenado o seu resultado é imprevisível: ele retornará qualquer valor que esteja armazenado na posição de memória alocada para armazenar o valor da variável `sim`.
|
||||
**4.** Vide arquivo `Sorts.c` na pasta da disciplina de Análise de Algoritmos e Estruturas de Dados I.
|
||||
|
||||
**5.** Vide arquivo `isSorted.c` nesta pasta.
|
||||
|
||||
## Exercícios 2
|
||||
**1.** Vide arquivo `sorts.c` na pasta da disciplina de Análise de Algoritmos e Estruturas de Dados I.
|
||||
|
||||
**2.** Continua, entretanto a função perderá sua propriedade de _estabilidade_, isso é, os valores iguais não aparecerão na mesma ordem quem que foram inseridos (estes figurarão em ordem reversa). Para ordenar valores inteiros isso não é de maior consequência senão por mais algumas comparações desnecessárias, mas quando estes valores são chaves para a ordenação de estruturas de dados, isso pode ser indesejável.
|
||||
|
||||
**3.**
|
||||
|
||||
**a)** Esta modificação não alterará o resultado, apenas adicionará uma repetição do loop descrito na linha 3 onde o valor em `v[j]` é copiado à `x` e em seguida sobrescrito à `v[j]`, pois nestas condições $i + 1 = j$.
|
||||
|
||||
**b)** Esta modificação comprometerá a funcionalidade do algoritmo. Fazendo com que o valor em `v[j]` seja armazenado uma posição antes do que deveria, possivelmente extrapolando o limite inferior do arranjo.
|
||||
|
||||
**4.** As consequências para a alteração
|
||||
|
||||
```diff
|
||||
6,7c5
|
||||
< v[i+1] = x;
|
||||
< }
|
||||
---
|
||||
> v[i] = x; } }
|
||||
\ No newline at end of file
|
||||
>
|
||||
```
|
||||
|
||||
São discutidas no item **b)** do exercício anterior.
|
||||
|
||||
**5.** Esta versão não alterará o resultado final do algoritmo, mas realizará um número maior de atribuições para alcançá-lo, o que prejudica seu desempenho.
|
||||
|
||||
**6.** Sim, a única diferença deste modelo com o algoritmo anteriormente descrito é o uso de um loop `while` em vez de um `for`. Assim, o invés de constar em uma única linha, temos que o contador é inicializado na linha 3, a condição de repetição na linha 4 e a incrementação do contador se dá na linha 6.
|
||||
|
||||
**7.** Vide o arquivo `backwards_insertion_sort.c`
|
||||
|
||||
**8.** Mas, isso pressupõe um vetor já ordenado. O resultado de se realizar esta operação terminaria por manter o vetor embaralhado.
|
||||
|
||||
**9.** O pior caso corresponde a qualquer instância em que os valores do vetor encontram-se ordenados em ordem decrescente. Assim, para um vetor de tamanho $n$ as comparações feitas ao final encontram-se em progressão aritmética:
|
||||
|
||||
$$1 + 2 + \dots + n - 1 = \dfrac{(n - 1)(n - 1 + 1)}2 = \dfrac{n^2 - n}2 \equiv O(n^2) $$
|
||||
|
||||
**10.** O melhor caso é aquele em que os valores já encontram-se em ordem crescente. Assimpara um vetor de tamanho $n$ cada valor desde o segundo ao último é comparado com seu antecessor uma única vez, um total de $n - 1 \equiv O(n)$ comparações realizadas .
|
||||
|
||||
**11.** No pior caso, todas as comparações levam à movimentação de dados, portanto, são $\frac{n^2 - n}2$ movimentações no total. No melhor caso, também. Neste os dados são copiados a uma variável temporária e em seguida sobrescritos sobre a posição donde advieram, totalizando $n - 1$ movimentações.
|
||||
|
||||
**12.** Vide o arquivo `backwards_insertion_sort.c`.
|
||||
|
||||
**13.**
|
||||
|
||||
**14.** Vide o arquivo `descrescent_insertion_sort.c`
|
||||
|
||||
## Exercícios 3
|
||||
|
||||
**1.** Vide arquivo `sorts.c` na pasta da disciplina de Análise de Algoritmos e Estruturas de Dados I.
|
||||
|
||||
**2.**
|
||||
|
||||
**a)** O primeiro elemento da lista não é ordenado.
|
||||
|
||||
**b)** Acrescenta-se uma repetição desnecessária, já que não à outro elemento com que comparar com o elemento final do vetor.
|
||||
|
||||
**3.** Sim, está correta, mas o algoritmo perde sua estabilidade. Elementos de mesmo valor são ordenados na ordem reversa daquela em que figuraram originalmente no vetor.
|
||||
|
||||
**4, 5 e 6.** Em ambos o melhor e o pior caso, o mesmo número de comparações são feitas, $\frac{n^2 - n}2$ o que diferencia estes dois casos é o número de movimentações feitas: respectivamente, $n - 1$ (os dados são copiados a uma variável temporária e em seguida sobrescritos sobre a posição donde advieram) e $\frac{n^2 - n}2$ (o último elemento vai para a primeira posição, o penúltimo a segunda, e assim por diante).
|
||||
|
||||
**7.** Vide o arquivo `descrescent_selection_sort.c`
|
||||
## Exercícios 4
|
||||
**1.** Vide o arquivo `string_insertion_sort.c`
|
||||
**2.** Vide o arquivo `string_radix_sort.c`
|
||||
**3 e 4.** Vide o arquivo `data_sort.c`
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
array readArray (int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
void swap (int *a, int *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
void shuffle(array A, int size) {
|
||||
if (--size < 1)
|
||||
return;
|
||||
swap(&A[rand() % size], &A[size]);
|
||||
shuffle(A, size);
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program shuffles integer values according to the "
|
||||
"Fisher-Yates algorithm.\nType in a sequence of values separated "
|
||||
"by spaces and press ENTER:\n");
|
||||
A = readArray(&size);
|
||||
shuffle(A, size);
|
||||
|
||||
printf("\nNew sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
int count, size;
|
||||
char **words;
|
||||
} Array;
|
||||
|
||||
typedef struct node {
|
||||
char *word;
|
||||
struct node *next;
|
||||
} Stack;
|
||||
|
||||
typedef struct {
|
||||
Stack **words, *max;
|
||||
int size, maxCount, *count, *order;
|
||||
} Dict;
|
||||
|
||||
/* Initializers */
|
||||
|
||||
Array *newArray() {
|
||||
Array *a = malloc(sizeof(Array));
|
||||
a->words = malloc(sizeof(char *));
|
||||
a->count = 0;
|
||||
a->size = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
Stack *newStack(char *word, Stack *next) {
|
||||
Stack *s = malloc(sizeof(Stack));
|
||||
s->word = word;
|
||||
s->next = next;
|
||||
return s;
|
||||
}
|
||||
|
||||
Dict *newDict(int size) {
|
||||
Dict *d = malloc(sizeof(Dict));
|
||||
|
||||
d->words = calloc(size, sizeof(Stack *));
|
||||
d->count = malloc(size * sizeof(int));
|
||||
d->maxCount = 0;
|
||||
d->size = size;
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Freeing memory */
|
||||
|
||||
void freeArray(Array *a) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
free(a->words[i]);
|
||||
free(a->words);
|
||||
free(a);
|
||||
}
|
||||
|
||||
void freeStack(Stack *s) {
|
||||
if (!s)
|
||||
return;
|
||||
freeStack(s->next);
|
||||
free(s);
|
||||
}
|
||||
|
||||
void freeDict(Dict *d) {
|
||||
int i = 0;
|
||||
|
||||
while (i < d->size)
|
||||
freeStack(d->words[i++]);
|
||||
free(d->words);
|
||||
free(d->count);
|
||||
free(d);
|
||||
}
|
||||
|
||||
/* Array insertion functions */
|
||||
|
||||
void insert(Array *a, char *buffer, int size) {
|
||||
char *new = malloc((size + 1) * sizeof(char));
|
||||
if (a->count == a->size - 1) {
|
||||
a->size *= 2;
|
||||
a->words = realloc(a->words, a->size * sizeof(char *));
|
||||
}
|
||||
a->words[a->count++] = strcpy(new, buffer);
|
||||
}
|
||||
|
||||
Array *readWords(FILE *f) {
|
||||
int size;
|
||||
char *buffer = malloc(64 * sizeof(char));
|
||||
Array *a = newArray();
|
||||
|
||||
while ((size = fscanf(f, " %s", buffer)) != EOF)
|
||||
insert(a, buffer, size);
|
||||
free(buffer);
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Stack insertion algorithm */
|
||||
|
||||
void push(Stack *head, char *word) {
|
||||
Stack *s = newStack(word, head->next);
|
||||
head->next = s;
|
||||
}
|
||||
|
||||
/* Sorting algorithm: quicksort */
|
||||
|
||||
void swap(char *a, char *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
char *median(char *a, char *b, char *c) {
|
||||
if ((*a > *b) ^ (*a > *c))
|
||||
return a;
|
||||
if ((*b < *a) ^ (*b < *c))
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
int partition(char *word, int size) {
|
||||
int i, j, last = size - 1;
|
||||
|
||||
swap(word + last, median(word, word + size / 2, word + last));
|
||||
for (i = j = 0; i < last; i++)
|
||||
if (word[i] <= word[last])
|
||||
swap(word + i, word + j++);
|
||||
swap(word + i, word + j);
|
||||
return j;
|
||||
}
|
||||
|
||||
void quickSort(char *word, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = partition(word, size);
|
||||
quickSort(word, pivot++);
|
||||
quickSort(word + pivot, size - pivot);
|
||||
}
|
||||
|
||||
/* Hash and rehash functions */
|
||||
|
||||
int key(char *word, int *i) {
|
||||
int k;
|
||||
for (*i = k = 0; word[*i]; (*i)++)
|
||||
k += word[*i];
|
||||
return k * (*i);
|
||||
}
|
||||
|
||||
int bits(int n) {
|
||||
n >>= 1;
|
||||
return (n) ? 1 + bits(n) : 1;
|
||||
}
|
||||
|
||||
int hash(int key, int mask, int b) {
|
||||
int index = key & mask;
|
||||
key >>= b;
|
||||
|
||||
return (key) ? index ^ hash(key, mask, b) : index;
|
||||
}
|
||||
|
||||
int rehash(int index, int i, int mask) { return (index + i * i) & mask; }
|
||||
|
||||
/* Dictionary insertion algorithm */
|
||||
|
||||
void add(Dict *d, char *word, int mask, int b) {
|
||||
int size, i, index = hash(key(word, &size), mask, b);
|
||||
char *charSet = malloc((size + 1) * sizeof(char));
|
||||
quickSort(strcpy(charSet, word), size);
|
||||
|
||||
for (i = 1; d->words[index] && strcmp(d->words[index]->word, charSet) != 0;
|
||||
i += 2)
|
||||
index = hash(index + i * i, mask, b);
|
||||
|
||||
if (!d->words[index]) {
|
||||
d->count[index] = 0;
|
||||
d->words[index] = newStack(charSet, NULL);
|
||||
} else
|
||||
free(charSet);
|
||||
push(d->words[index], word);
|
||||
d->count[index]++;
|
||||
|
||||
if (d->count[index] > d->maxCount) {
|
||||
d->maxCount = d->count[index];
|
||||
d->max = d->words[index];
|
||||
}
|
||||
}
|
||||
|
||||
Dict *buildDict(Array *a) {
|
||||
int i, mask = a->size - 1, b = bits(mask);
|
||||
Dict *d = newDict(a->size);
|
||||
|
||||
for (i = 0; i < a->count; i++)
|
||||
add(d, a->words[i], mask, b);
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Printing functions */
|
||||
|
||||
void printStack(Stack *s, char *terminator) {
|
||||
if (!s)
|
||||
return;
|
||||
printStack(s->next, ", ");
|
||||
printf("%s%s", s->word, terminator);
|
||||
}
|
||||
|
||||
void printMax(Dict *d) {
|
||||
printf(
|
||||
"O conjunto de caracteres que possibilita o maior número de anagramas "
|
||||
"na lingua portuguesa é \"%s\", que permite formar %d anagramas: ",
|
||||
d->max->word, d->maxCount);
|
||||
printStack(d->max->next, ".\n");
|
||||
}
|
||||
|
||||
/* Main function */
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *f = fopen(argv[1], "r");
|
||||
Array *a = readWords(f);
|
||||
Dict *d = buildDict(a);
|
||||
|
||||
printMax(d);
|
||||
fclose(f);
|
||||
freeArray(a);
|
||||
freeDict(d);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,267 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
int count, size;
|
||||
char **words;
|
||||
} Array;
|
||||
|
||||
typedef struct node {
|
||||
char *word;
|
||||
struct node *next;
|
||||
} Stack;
|
||||
|
||||
typedef struct {
|
||||
Stack **words, *max;
|
||||
int size, sets, maxCount, *count, *order;
|
||||
} Dict;
|
||||
|
||||
/* Initializers */
|
||||
|
||||
Array *newArray() {
|
||||
Array *a = malloc(sizeof(Array));
|
||||
a->words = malloc(sizeof(char *));
|
||||
a->count = 0;
|
||||
a->size = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
Stack *newStack(char *word, Stack *next) {
|
||||
Stack *s = malloc(sizeof(Stack));
|
||||
s->word = word;
|
||||
s->next = next;
|
||||
return s;
|
||||
}
|
||||
|
||||
Dict *newDict(int size) {
|
||||
Dict *d = malloc(sizeof(Dict));
|
||||
|
||||
d->words = calloc(size, sizeof(Stack *));
|
||||
d->count = malloc(size * sizeof(int));
|
||||
d->order = malloc(size * sizeof(int));
|
||||
d->maxCount = d->sets = 0;
|
||||
d->size = size;
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Freeing memory */
|
||||
|
||||
void freeArray(Array *a) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
free(a->words[i]);
|
||||
free(a->words);
|
||||
free(a);
|
||||
}
|
||||
|
||||
void freeStack(Stack *s) {
|
||||
if (!s)
|
||||
return;
|
||||
freeStack(s->next);
|
||||
free(s);
|
||||
}
|
||||
|
||||
void freeDict(Dict *d) {
|
||||
int i = 0;
|
||||
|
||||
while (i < d->size)
|
||||
freeStack(d->words[i++]);
|
||||
free(d->words);
|
||||
free(d->count);
|
||||
free(d);
|
||||
}
|
||||
|
||||
/* Array insertion functions */
|
||||
|
||||
void insert(Array *a, char *buffer, int size) {
|
||||
char *new = malloc((size + 1) * sizeof(char));
|
||||
if (a->count == a->size - 1) {
|
||||
a->size *= 2;
|
||||
a->words = realloc(a->words, a->size * sizeof(char *));
|
||||
}
|
||||
a->words[a->count++] = strcpy(new, buffer);
|
||||
}
|
||||
|
||||
Array *readWords(FILE *f) {
|
||||
int size;
|
||||
char *buffer = malloc(64 * sizeof(char));
|
||||
Array *a = newArray();
|
||||
|
||||
while ((size = fscanf(f, " %s", buffer)) != EOF)
|
||||
insert(a, buffer, size);
|
||||
free(buffer);
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Stack insertion algorithm */
|
||||
|
||||
void push(Stack *head, char *word) {
|
||||
Stack *s = newStack(word, head->next);
|
||||
head->next = s;
|
||||
}
|
||||
|
||||
/* Sorting algorithms */
|
||||
|
||||
void swap(char *a, char *b) {
|
||||
char tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
char *median(char *a, char *b, char *c) {
|
||||
if ((*a > *b) ^ (*a > *c))
|
||||
return a;
|
||||
if ((*b < *a) ^ (*b < *c))
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
int partition(char *word, int size) {
|
||||
int i, j, last = size - 1;
|
||||
|
||||
swap(word + last, median(word, word + size / 2, word + last));
|
||||
for (i = j = 0; i < last; i++)
|
||||
if (word[i] <= word[last])
|
||||
swap(word + i, word + j++);
|
||||
swap(word + i, word + j);
|
||||
return j;
|
||||
}
|
||||
|
||||
void quickSort(char *word, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = partition(word, size);
|
||||
quickSort(word, pivot++);
|
||||
quickSort(word + pivot, size - pivot);
|
||||
}
|
||||
|
||||
char *countingSort(char *word, int size, int mask) {
|
||||
int i, j;
|
||||
char *sorted = malloc(size * sizeof(char));
|
||||
|
||||
for (i = j = 0; i < size; i++)
|
||||
if (!(word[i] & mask))
|
||||
sorted[j++] = word[i];
|
||||
for (i = 0; i < size; i++)
|
||||
if (word[i] & mask)
|
||||
sorted[j++] = word[i];
|
||||
free(word);
|
||||
return sorted;
|
||||
}
|
||||
|
||||
char *radixSort(char *word, int size, int length) {
|
||||
while (length >> 1)
|
||||
word = countingSort(word, size, length);
|
||||
return word;
|
||||
}
|
||||
|
||||
/* Hash and rehash functions */
|
||||
|
||||
int key(char *word, int *i) {
|
||||
int k;
|
||||
for (*i = k = 0; word[*i]; (*i)++)
|
||||
k += word[*i];
|
||||
return k * (*i);
|
||||
}
|
||||
|
||||
int bits(int n) {
|
||||
n >>= 1;
|
||||
return (n) ? 1 + bits(n) : 1;
|
||||
}
|
||||
|
||||
int hash(int key, int mask, int b) {
|
||||
int index = key & mask;
|
||||
key >>= b;
|
||||
|
||||
return (key) ? index ^ hash(key, mask, b) : index;
|
||||
}
|
||||
|
||||
int rehash(int index, int i, int mask) { return (index + i * i) & mask; }
|
||||
|
||||
/* Dictionary insertion algorithm */
|
||||
|
||||
void add(Dict *d, char *word, int mask, int b) {
|
||||
int size, i, index = hash(key(word, &size), mask, b);
|
||||
char *charSet = malloc((size + 1) * sizeof(char));
|
||||
quickSort(strcpy(charSet, word), size);
|
||||
|
||||
// Alternative:
|
||||
// char *charSet = radixSort(strcpy(malloc((size + 1) * sizeof(char)),
|
||||
// word), size, CHAR_BIT * sizeof(char));
|
||||
|
||||
for (i = 1; d->words[index] && strcmp(d->words[index]->word, charSet) != 0;
|
||||
i += 2)
|
||||
index = hash(index + i * i, mask, b);
|
||||
|
||||
if (!d->words[index]) {
|
||||
d->words[index] = newStack(charSet, NULL);
|
||||
d->order[d->sets++] = index;
|
||||
d->count[index] = 0;
|
||||
} else
|
||||
free(charSet);
|
||||
push(d->words[index], word);
|
||||
d->count[index]++;
|
||||
|
||||
if (d->count[index] > d->maxCount) {
|
||||
d->maxCount = d->count[index];
|
||||
d->max = d->words[index];
|
||||
}
|
||||
}
|
||||
|
||||
Dict *buildDict(Array *a) {
|
||||
int i, mask = a->size - 1, b = bits(mask);
|
||||
Dict *d = newDict(a->size);
|
||||
|
||||
for (i = 0; i < a->count; i++)
|
||||
add(d, a->words[i], mask, b);
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Printing functions */
|
||||
|
||||
void printStack(Stack *s, char *terminator) {
|
||||
if (!s)
|
||||
return;
|
||||
printStack(s->next, ", ");
|
||||
printf("%s%s", s->word, terminator);
|
||||
}
|
||||
|
||||
void printMax(Dict *d) {
|
||||
printf(
|
||||
"O conjunto de caracteres que possibilita o maior número de anagramas "
|
||||
"na lingua portuguesa é \"%s\", que permite formar %d anagramas: ",
|
||||
d->max->word, d->maxCount);
|
||||
printStack(d->max->next, ".\n");
|
||||
}
|
||||
|
||||
void printSets(Dict *d) {
|
||||
int i;
|
||||
printf("\nOs conjuntos de anagramas com mais de um item são:\n");
|
||||
for (i = 0; i < d->sets; i++) {
|
||||
if (d->count[d->order[i]] < 2)
|
||||
continue;
|
||||
printf("Conjunto \"%s\", %d anagramas: ", d->words[d->order[i]]->word,
|
||||
d->count[d->order[i]]);
|
||||
printStack(d->words[d->order[i]]->next, ".\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Main function */
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *f = fopen(argv[1], "r");
|
||||
Array *a = readWords(f);
|
||||
Dict *d = buildDict(a);
|
||||
|
||||
printMax(d);
|
||||
printSets(d);
|
||||
fclose(f);
|
||||
freeArray(a);
|
||||
freeDict(d);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct {
|
||||
int count, size;
|
||||
char **words;
|
||||
} Array;
|
||||
|
||||
typedef struct node {
|
||||
char *word;
|
||||
struct node *next;
|
||||
} Stack;
|
||||
|
||||
typedef struct {
|
||||
Stack **words, *max;
|
||||
int size, sets, maxCount, *count, *order;
|
||||
} Dict;
|
||||
|
||||
/* Initializers */
|
||||
|
||||
Array *newArray() {
|
||||
Array *a = malloc(sizeof(Array));
|
||||
a->words = malloc(sizeof(char *));
|
||||
a->count = 0;
|
||||
a->size = 1;
|
||||
return a;
|
||||
}
|
||||
|
||||
Stack *newStack(char *word, Stack *next) {
|
||||
Stack *s = malloc(sizeof(Stack));
|
||||
s->word = word;
|
||||
s->next = next;
|
||||
return s;
|
||||
}
|
||||
|
||||
Dict *newDict(int size) {
|
||||
Dict *d = malloc(sizeof(Dict));
|
||||
|
||||
d->words = calloc(size, sizeof(Stack *));
|
||||
d->count = malloc(size * sizeof(int));
|
||||
d->order = malloc(size * sizeof(int));
|
||||
d->maxCount = d->sets = 0;
|
||||
d->size = size;
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Freeing memory */
|
||||
|
||||
void freeArray(Array *a) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < a->size; i++)
|
||||
free(a->words[i]);
|
||||
free(a->words);
|
||||
free(a);
|
||||
}
|
||||
|
||||
void freeStack(Stack *s) {
|
||||
if (!s)
|
||||
return;
|
||||
freeStack(s->next);
|
||||
free(s);
|
||||
}
|
||||
|
||||
void freeDict(Dict *d) {
|
||||
int i = 0;
|
||||
|
||||
while (i < d->size)
|
||||
freeStack(d->words[i++]);
|
||||
free(d->words);
|
||||
free(d->count);
|
||||
free(d);
|
||||
}
|
||||
|
||||
/* Array insertion functions */
|
||||
|
||||
void insert(Array *a, char *buffer, int size) {
|
||||
char *new = malloc((size + 1) * sizeof(char));
|
||||
if (a->count == a->size - 1) {
|
||||
a->size *= 2;
|
||||
a->words = realloc(a->words, a->size * sizeof(char *));
|
||||
}
|
||||
a->words[a->count++] = strcpy(new, buffer);
|
||||
}
|
||||
|
||||
Array *readWords(FILE *f) {
|
||||
int size;
|
||||
char *buffer = malloc(64 * sizeof(char));
|
||||
Array *a = newArray();
|
||||
|
||||
while ((size = fscanf(f, " %s", buffer)) != EOF)
|
||||
insert(a, buffer, size);
|
||||
free(buffer);
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Stack insertion algorithm */
|
||||
|
||||
void push(Stack *head, char *word) {
|
||||
Stack *s = newStack(word, head->next);
|
||||
head->next = s;
|
||||
}
|
||||
|
||||
/* Sorting algorithms */
|
||||
|
||||
void insertionSort(char *word, int size) {
|
||||
int i, tmp;
|
||||
|
||||
if (size-- <= 1)
|
||||
return;
|
||||
insertionSort(word, size);
|
||||
tmp = word[size];
|
||||
for (i = size; i > 0 && word[i - 1] > tmp; i--)
|
||||
word[i] = word[i - 1];
|
||||
word[i] = tmp;
|
||||
}
|
||||
|
||||
/* Hash and rehash functions */
|
||||
|
||||
int key(char *word, int *i) {
|
||||
int k;
|
||||
for (*i = k = 0; word[*i]; (*i)++)
|
||||
k += word[*i];
|
||||
return k * (*i);
|
||||
}
|
||||
|
||||
int bits(int n) {
|
||||
n >>= 1;
|
||||
return (n) ? 1 + bits(n) : 1;
|
||||
}
|
||||
|
||||
int hash(int key, int mask, int b) {
|
||||
int index = key & mask;
|
||||
key >>= b;
|
||||
|
||||
return (key) ? index ^ hash(key, mask, b) : index;
|
||||
}
|
||||
|
||||
int rehash(int index, int i, int mask) { return (index + i * i) & mask; }
|
||||
|
||||
/* Dictionary insertion algorithm */
|
||||
|
||||
void add(Dict *d, char *word, int mask, int b) {
|
||||
int size, i, index = hash(key(word, &size), mask, b);
|
||||
char *charSet = malloc((size + 1) * sizeof(char));
|
||||
insertionSort(strcpy(charSet, word), size);
|
||||
|
||||
// Alternative:
|
||||
// char *charSet = radixSort(strcpy(malloc((size + 1) * sizeof(char)),
|
||||
// word), size, CHAR_BIT * sizeof(char));
|
||||
|
||||
for (i = 1; d->words[index] && strcmp(d->words[index]->word, charSet) != 0;
|
||||
i += 2)
|
||||
index = hash(index + i * i, mask, b);
|
||||
|
||||
if (!d->words[index]) {
|
||||
d->words[index] = newStack(charSet, NULL);
|
||||
d->order[d->sets++] = index;
|
||||
d->count[index] = 0;
|
||||
} else
|
||||
free(charSet);
|
||||
push(d->words[index], word);
|
||||
d->count[index]++;
|
||||
|
||||
if (d->count[index] > d->maxCount) {
|
||||
d->maxCount = d->count[index];
|
||||
d->max = d->words[index];
|
||||
}
|
||||
}
|
||||
|
||||
Dict *buildDict(Array *a) {
|
||||
int i, mask = a->size - 1, b = bits(mask);
|
||||
Dict *d = newDict(a->size);
|
||||
|
||||
for (i = 0; i < a->count; i++)
|
||||
add(d, a->words[i], mask, b);
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Printing functions */
|
||||
|
||||
void printStack(Stack *s, char *terminator) {
|
||||
if (!s)
|
||||
return;
|
||||
printStack(s->next, ", ");
|
||||
printf("%s%s", s->word, terminator);
|
||||
}
|
||||
|
||||
void printMax(Dict *d) {
|
||||
printf(
|
||||
"O conjunto de caracteres que possibilita o maior número de anagramas "
|
||||
"na lingua portuguesa é \"%s\", que permite formar %d anagramas: ",
|
||||
d->max->word, d->maxCount);
|
||||
printStack(d->max->next, ".\n");
|
||||
}
|
||||
|
||||
void printSets(Dict *d) {
|
||||
int i;
|
||||
printf("\nOs conjuntos de anagramas com mais de um item são:\n");
|
||||
for (i = 0; i < d->sets; i++) {
|
||||
if (d->count[d->order[i]] < 2)
|
||||
continue;
|
||||
printf("Conjunto \"%s\", %d anagramas: ", d->words[d->order[i]]->word,
|
||||
d->count[d->order[i]]);
|
||||
printStack(d->words[d->order[i]]->next, ".\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Main function */
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *f = fopen(argv[1], "r");
|
||||
Array *a = readWords(f);
|
||||
Dict *d = buildDict(a);
|
||||
|
||||
printMax(d);
|
||||
printSets(d);
|
||||
fclose(f);
|
||||
freeArray(a);
|
||||
freeDict(d);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
void insertionSort (array A, int size) {
|
||||
int i, tmp;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
--size;
|
||||
insertionSort(A + 1, size);
|
||||
tmp = A[0];
|
||||
for (i = 0; i < size && A[i + 1] < tmp; i++)
|
||||
A[i] = A[i + 1];
|
||||
A[i] = tmp;
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
insertionSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
void swap (int *a, int *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
void bubbleSort (array A, int size) {
|
||||
int i;
|
||||
|
||||
if (size-- <= 1)
|
||||
return;
|
||||
for (i = 0; i < size; i++)
|
||||
if (A[i] > A[i + 1])
|
||||
swap(&A[i], &A[i + 1]);
|
||||
bubbleSort(A, size);
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
bubbleSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
typedef struct {
|
||||
int key;
|
||||
wchar_t *data;
|
||||
} Node;
|
||||
|
||||
typedef struct {
|
||||
Node *items;
|
||||
int size;
|
||||
} Array;
|
||||
|
||||
/* Freeing memory*/
|
||||
|
||||
void freeArray(Array *A) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < A->size; i++)
|
||||
free(A->items[i].data);
|
||||
free(A->items);
|
||||
free(A);
|
||||
}
|
||||
|
||||
/* Read functions */
|
||||
|
||||
bool readLine(wchar_t **line) {
|
||||
int i = 0, length = 1;
|
||||
wchar_t c;
|
||||
|
||||
*line = malloc(sizeof(wchar_t));
|
||||
while ((c = getwchar()) != WEOF && c != '\n') {
|
||||
if (i == length - 1) {
|
||||
length *= 2;
|
||||
*line = realloc(*line, length * sizeof(wchar_t));
|
||||
}
|
||||
(*line)[i++] = c;
|
||||
}
|
||||
(*line)[i] = '\0';
|
||||
|
||||
if (i)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Array *readText() {
|
||||
Array *A = malloc(sizeof(Array));
|
||||
int i;
|
||||
|
||||
A->items = malloc(sizeof(Node));
|
||||
A->size = 1;
|
||||
for (i = 0; readLine(&(A->items[i].data)); i++) {
|
||||
A->items[i].key = i;
|
||||
if (i < A->size - 1)
|
||||
continue;
|
||||
A->size *= 2;
|
||||
A->items = realloc(A->items, A->size * sizeof(Node));
|
||||
}
|
||||
A->size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
/* Sort wchars */
|
||||
|
||||
void swap(Node *a, Node *b) {
|
||||
Node tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
bool compareRadix (wchar_t *a, wchar_t *b) {
|
||||
int i;
|
||||
|
||||
for (i = 0; a[i] != '\0'; i++) {
|
||||
if (a[i] > b[i] || b[i] == '\0')
|
||||
return true;
|
||||
if (a[i] < b[i])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Node * medianOfDatasets(Node *a, Node *b, Node *c) {
|
||||
if (compareRadix(a->data, b->data) ^ compareRadix(a->data, b->data))
|
||||
return a;
|
||||
if (compareRadix(a->data, b->data) ^ compareRadix(c->data, b->data))
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
int partitionByData (Node *n, int size) {
|
||||
int i, j, last = size - 1;
|
||||
|
||||
swap(n + last, medianOfDatasets(n, n + size / 2, n + last));
|
||||
for (i = j = 0; i < last; i++)
|
||||
if (compareRadix(n[last].data, n[i].data))
|
||||
swap(&n[i], &n[j++]);
|
||||
swap(&n[i], &n[j]);
|
||||
return j;
|
||||
}
|
||||
|
||||
void quickSortData (Node *n, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = partitionByData(n, size);
|
||||
quickSortData(n, pivot++);
|
||||
quickSortData(n + pivot, size - pivot);
|
||||
}
|
||||
|
||||
/* Sort ints */
|
||||
|
||||
Node * medianOfKeys(Node *a, Node *b, Node *c) {
|
||||
if ((a->key > b->key) ^ (a->key > c->key))
|
||||
return a;
|
||||
if ((b->key < a->key) ^ (b->key < c->key))
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
int partitionByKey (Node *n, int size) {
|
||||
int i, j, last = size - 1;
|
||||
|
||||
swap(n + last, medianOfKeys(n, n + size / 2, n + last));
|
||||
for (i = j = 0; i < last; i++)
|
||||
if (n[i].key <= n[last].key)
|
||||
swap(&n[i], &n[j++]);
|
||||
swap(&n[i], &n[j]);
|
||||
return j;
|
||||
}
|
||||
|
||||
void quickSortKeys (Node *n, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = partitionByKey(n, size);
|
||||
quickSortKeys(n, pivot++);
|
||||
quickSortKeys(n + pivot, size - pivot);
|
||||
}
|
||||
|
||||
/* Driver function */
|
||||
|
||||
int main () {
|
||||
setlocale(LC_ALL, "pt_BR.UTF-8");
|
||||
Array *A;
|
||||
int i;
|
||||
|
||||
wprintf(L"This program orders the lines of a text in lexicographic "
|
||||
L"order, and then by their insertion order.\nType in a sequence "
|
||||
L"of lines and press Enter twice:\n");
|
||||
A = readText();
|
||||
|
||||
quickSortData(A->items, A->size);
|
||||
wprintf(L"\nSort by data:\n");
|
||||
for (i = 0; i < A->size; i++)
|
||||
wprintf(L"%ls\n", A->items[i].data);
|
||||
|
||||
quickSortKeys(A->items, A->size);
|
||||
|
||||
wprintf(L"\nSort by key:\n");
|
||||
for (i = 0; i < A->size; i++)
|
||||
wprintf(L"%ls\n", A->items[i].data);
|
||||
|
||||
freeArray(A);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
void insertionSort (array A, int size) {
|
||||
int i, tmp;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
--size;
|
||||
insertionSort(A + 1, size);
|
||||
tmp = A[0];
|
||||
for (i = 0; i < size && A[i + 1] > tmp; i++)
|
||||
A[i] = A[i + 1];
|
||||
A[i] = tmp;
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
insertionSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define array int *
|
||||
|
||||
void swap(int *a, int *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
int *maximalValue(array A, int size) {
|
||||
int i, pos = 0;
|
||||
|
||||
for (i = 1; i < size; i++)
|
||||
if (A[i] > A[pos])
|
||||
pos = i;
|
||||
return A + pos;
|
||||
}
|
||||
|
||||
void selectionSort(array A, int size) {
|
||||
if (size <= 1)
|
||||
return;
|
||||
swap(A, maximalValue(A, size));
|
||||
selectionSort(A + 1, size - 1);
|
||||
}
|
||||
|
||||
array readArray(int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main() {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs a selection sort.\nType in a sequence of "
|
||||
"values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
selectionSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
void swap (int *a, int *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
void heapify (array A, int size, int i) {
|
||||
int max = i, left = 2 * max + 1, right = left + 1;
|
||||
|
||||
if (left >= size)
|
||||
return;
|
||||
if (A[left] > A[max])
|
||||
max = left;
|
||||
if (right < size && A[right] > A[max])
|
||||
max = right;
|
||||
else if (max == i)
|
||||
return;
|
||||
|
||||
swap(A + i, A + max);
|
||||
heapify(A, size, max);
|
||||
}
|
||||
|
||||
void heapSort (array A, int size) {
|
||||
int i;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
|
||||
for (i = (size - 1) / 2; i <= 0; i--)
|
||||
heapify(A, size, i);
|
||||
|
||||
for (i = size - 1; i > 0; i--) {
|
||||
swap(A, A + i);
|
||||
heapify(A, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
heapSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
void insertionSort (array A, int size) {
|
||||
int i, tmp;
|
||||
|
||||
if (size-- <= 1)
|
||||
return;
|
||||
insertionSort(A, size);
|
||||
tmp = A[size];
|
||||
for (i = size; i > 0 && A[i - 1] > tmp; i--)
|
||||
A[i] = A[i - 1];
|
||||
A[i] = tmp;
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
insertionSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct array{
|
||||
int *values;
|
||||
int size, buffer;
|
||||
} Array;
|
||||
|
||||
Array * readArray () {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
Array *A = malloc(sizeof(Array));
|
||||
|
||||
A->buffer = 1;
|
||||
A->values = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == A->buffer - 1) {
|
||||
A->buffer *= 2;
|
||||
A->values = realloc(A->values, A->buffer * sizeof(int));
|
||||
}
|
||||
A->values[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
A->size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
bool isSorted(int* A, int size) {
|
||||
if (size <= 1)
|
||||
return true;
|
||||
if (*A > *(A + 1))
|
||||
return false;
|
||||
return isSorted(A + 1, size - 1);
|
||||
}
|
||||
|
||||
void insertIn (Array **A, int value) {
|
||||
int i;
|
||||
Array *B;
|
||||
|
||||
if ((*A)->size + 1 > (*A)->buffer) {
|
||||
B = malloc(sizeof(Array));
|
||||
B->size = (*A)->size + 1;
|
||||
B->buffer = (*A)->buffer * 2;
|
||||
B->values = malloc(B->buffer * sizeof(int));
|
||||
|
||||
for (i = 0; i < (*A)->size && (*A)->values[i] <= value; i++)
|
||||
B->values[i] = (*A)->values[i];
|
||||
B->values[i] = value;
|
||||
while(++i <= (*A)->size)
|
||||
B->values[i] = (*A)->values[i - 1];
|
||||
|
||||
free(*A);
|
||||
*A = B;
|
||||
}
|
||||
else {
|
||||
for (i = (*A)->size - 1; i >= 0 && (*A)->values[i] > value; i--)
|
||||
(*A)->values[i + 1] = (*A)->values[i];
|
||||
(*A)->values[i + 1] = value;
|
||||
(*A)->size++;
|
||||
}
|
||||
}
|
||||
|
||||
int main () {
|
||||
Array *A;
|
||||
int i, value;
|
||||
|
||||
printf("This program evaluates if a sequence of integer values is sorted in crescent order and, if it is, allows for the insertion of a new integer value to it.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray();
|
||||
|
||||
if (!isSorted(A->values, A->size)) {
|
||||
printf("Not sorted in crescent order.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Sorted in crescent order. Type a integer value to be added to it: ");
|
||||
if (!scanf(" %d", &value)) {
|
||||
printf("Not an integer\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
insertIn(&A, value);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < A->size; i++)
|
||||
printf("%d ", A->values[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node{
|
||||
int key;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
Node * read() {
|
||||
int key;
|
||||
char c;
|
||||
Node *HEAD, *current, *prev;
|
||||
|
||||
if (!scanf(" %d", &key))
|
||||
return NULL;
|
||||
HEAD = malloc(sizeof(Node));
|
||||
HEAD->key = key;
|
||||
prev = HEAD;
|
||||
current = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n') {
|
||||
if (!scanf("%d", &key))
|
||||
break;
|
||||
current = malloc(sizeof(Node));
|
||||
current->key = key;
|
||||
prev->next = current;
|
||||
prev = current;
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->next = NULL;
|
||||
else
|
||||
HEAD->next = NULL;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
Node * insert (Node *HEAD) {
|
||||
Node *tmp = HEAD, *prev = tmp->next, *next;
|
||||
|
||||
HEAD = prev;
|
||||
for (next = prev->next; next && tmp->key > next->key; next = next->next)
|
||||
prev = next;
|
||||
|
||||
prev->next = tmp;
|
||||
tmp->next = next;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
Node * insertionSort (Node *HEAD) {
|
||||
if (HEAD) {
|
||||
HEAD->next = insertionSort(HEAD->next);
|
||||
if (HEAD->next && HEAD->key > HEAD->next->key)
|
||||
return insert(HEAD);
|
||||
}
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
void printList(Node *n) {
|
||||
printf("\nNew sequence:\n");
|
||||
while (n) {
|
||||
printf("%d ", n->key);
|
||||
n = n->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main () {
|
||||
printf("This program sorts a linked list based on its nodes' keys values."
|
||||
"\nType in a sequence of integer values separated by spaces and "
|
||||
"press ENTER: ");
|
||||
printList(insertionSort(read()));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node{
|
||||
int key;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
Node * read() {
|
||||
int key;
|
||||
char c;
|
||||
Node *HEAD, *current, *prev;
|
||||
|
||||
if (!scanf(" %d", &key))
|
||||
return NULL;
|
||||
HEAD = malloc(sizeof(Node));
|
||||
HEAD->key = key;
|
||||
prev = HEAD;
|
||||
current = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n') {
|
||||
if (!scanf("%d", &key))
|
||||
break;
|
||||
current = malloc(sizeof(Node));
|
||||
current->key = key;
|
||||
prev->next = current;
|
||||
prev = current;
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->next = NULL;
|
||||
else
|
||||
HEAD->next = NULL;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
Node * minimalValue(Node *HEAD, Node **prev) {
|
||||
Node *current, *min;
|
||||
|
||||
*prev = NULL;
|
||||
for (current = min = HEAD; current->next; current = current->next) {
|
||||
if (current->next->key >= min->key)
|
||||
continue;
|
||||
min = current->next;
|
||||
*prev = current;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
Node * swap (Node *HEAD, Node *prev, Node *min) {
|
||||
Node *next;
|
||||
|
||||
if (HEAD != min) {
|
||||
next = min->next;
|
||||
prev->next = HEAD;
|
||||
min->next = HEAD->next;
|
||||
HEAD->next = next;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
Node * selectionSort (Node *HEAD) {
|
||||
Node *prev;
|
||||
|
||||
if (HEAD){
|
||||
HEAD = swap(HEAD, prev, minimalValue(HEAD, &prev));
|
||||
HEAD->next = selectionSort(HEAD->next);
|
||||
}
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
void printList(Node *n) {
|
||||
printf("\nNew sequence:\n");
|
||||
while (n) {
|
||||
printf("%d ", n->key);
|
||||
n = n->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main () {
|
||||
printf("This program sorts a linked list based on its nodes' keys "
|
||||
"values.\nType in a sequence of integer values and press ENTER: ");
|
||||
printList(selectionSort(read()));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
int findMax(array A, int size) {
|
||||
int i, max = A[0];
|
||||
|
||||
for(i = 1; i < size; i++)
|
||||
if (A[i] > max)
|
||||
max = A[i];
|
||||
return max;
|
||||
}
|
||||
|
||||
array cumulativeFreq (array A, int size, int exp) {
|
||||
int i, radix;
|
||||
array frequency = calloc(19, sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
radix = A[i] / exp % 10;
|
||||
frequency[10 + radix]++;
|
||||
}
|
||||
for (i = 1; i < 18; i++)
|
||||
frequency[i] += frequency[i - 1];
|
||||
return frequency;
|
||||
}
|
||||
|
||||
void countingSort (array *A, int size, int exp) {
|
||||
int i, radix;
|
||||
array count = cumulativeFreq(*A, size, exp);
|
||||
array sorted = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
radix = (*A)[i] / exp % 10;
|
||||
sorted[count[9 + radix]++] = (*A)[i];
|
||||
}
|
||||
free(*A);
|
||||
free(count);
|
||||
*A = sorted;
|
||||
}
|
||||
|
||||
void radixSort(array *A, int size) {
|
||||
int exp, max = findMax(*A, size);
|
||||
|
||||
for (exp = 1; max / exp > 0; exp *= 10)
|
||||
countingSort(A, size, exp);
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
radixSort(&A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#include <malloc.h>
|
||||
|
||||
int *set(int *orderedArray, int size, int *count) {
|
||||
int i, *result = malloc(size * sizeof(int));
|
||||
*result = *orderedArray;
|
||||
|
||||
for (i = *count = 1; i < size; i++)
|
||||
if (orderedArray[i] != orderedArray[i - 1])
|
||||
result[*count++] = orderedArray[i];
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
typedef struct {
|
||||
wchar_t **lines;
|
||||
int lineCount;
|
||||
} Text;
|
||||
|
||||
bool readLine(wchar_t **line) {
|
||||
int i = 0, length = 1;
|
||||
wchar_t c;
|
||||
|
||||
*line = malloc(sizeof(wchar_t));
|
||||
while ((c = getwchar()) != WEOF && c != '\n') {
|
||||
if (i == length - 1) {
|
||||
length *= 2;
|
||||
*line = realloc(*line, length * sizeof(wchar_t));
|
||||
}
|
||||
(*line)[i++] = c;
|
||||
}
|
||||
(*line)[i] = '\0';
|
||||
|
||||
if (i)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void freeLines(wchar_t **lines, int i, int size) {
|
||||
while (i < size)
|
||||
free(lines[i++]);
|
||||
}
|
||||
|
||||
Text *readText() {
|
||||
Text *t = malloc(sizeof(Text));
|
||||
int i;
|
||||
|
||||
t->lines = malloc(sizeof(wchar_t *));
|
||||
t->lineCount = 1;
|
||||
for (i = 0; readLine(t->lines + i); i++) {
|
||||
if (i < t->lineCount - 1)
|
||||
continue;
|
||||
t->lineCount *= 2;
|
||||
t->lines = realloc(t->lines, t->lineCount * sizeof(wchar_t *));
|
||||
}
|
||||
|
||||
freeLines(t->lines, i, t->lineCount);
|
||||
t->lineCount = i;
|
||||
return t;
|
||||
}
|
||||
|
||||
void insertionSort(wchar_t **lines, int size) {
|
||||
int i;
|
||||
wchar_t *tmp;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
--size;
|
||||
insertionSort(lines, size);
|
||||
tmp = lines[size];
|
||||
for (i = size; i > 0 && wcscmp(lines[i - 1], tmp) > 0; i--)
|
||||
lines[i] = lines[i - 1];
|
||||
lines[i] = tmp;
|
||||
}
|
||||
|
||||
int main() {
|
||||
setlocale(LC_ALL, "pt_BR.UTF-8");
|
||||
Text *t;
|
||||
int i;
|
||||
|
||||
wprintf(L"This program orders the lines of a text in lexicographic "
|
||||
L"order.\nType in a sequence of lines and press Enter twice:\n");
|
||||
t = readText();
|
||||
insertionSort(t->lines, t->lineCount);
|
||||
|
||||
wprintf(L"New sequence:\n");
|
||||
for (i = 0; i < t->lineCount; i++)
|
||||
wprintf(L"%ls\n", t->lines[i]);
|
||||
freeLines(t->lines, 0, t->lineCount);
|
||||
free(t->lines);
|
||||
free(t);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
void freeLines(wchar_t **lines) {
|
||||
int i;
|
||||
|
||||
for (i = 0; lines[i][0] != '\0'; i++)
|
||||
free(lines[i]);
|
||||
free(lines[i]);
|
||||
}
|
||||
|
||||
void readLine(wchar_t **line, wchar_t c, int i, int length) {
|
||||
if (c == '\n' || c == WEOF) {
|
||||
(*line)[i] = '\0';
|
||||
return;
|
||||
}
|
||||
(*line)[i] = c;
|
||||
if (i == length - 1) {
|
||||
length *= 2;
|
||||
*line = realloc(*line, length * sizeof(wchar_t));
|
||||
}
|
||||
readLine(line, getwchar(), i + 1, length);
|
||||
}
|
||||
|
||||
wchar_t **readLines() {
|
||||
int i = 0, lines = 1;
|
||||
wchar_t **text = malloc(sizeof(wchar_t *));
|
||||
|
||||
do {
|
||||
text[i] = malloc(sizeof(wchar_t));
|
||||
readLine(text + i, getwchar(), 0, 1);
|
||||
if (i < lines - 1)
|
||||
continue;
|
||||
lines *= 2;
|
||||
text = realloc(text, lines * sizeof(wchar_t *));
|
||||
} while (text[i++][0] != '\0');
|
||||
return text;
|
||||
}
|
||||
|
||||
void insertionSort(wchar_t **lines) {
|
||||
int i;
|
||||
wchar_t *tmp;
|
||||
|
||||
if (lines[1][0] == '\0')
|
||||
return;
|
||||
insertionSort(lines + 1);
|
||||
tmp = *lines;
|
||||
for (i = 0; lines[i + 1][0] != '\0' && wcscmp(lines[i + 1], tmp) < 0; i++)
|
||||
lines[i] = lines[i + 1];
|
||||
lines[i] = tmp;
|
||||
}
|
||||
|
||||
int main() {
|
||||
setlocale(LC_ALL, "pt_BR.UTF-8");
|
||||
wchar_t **t;
|
||||
int i;
|
||||
|
||||
wprintf(L"This program orders the lines of a text in lexicographic "
|
||||
L"order.\nType in a sequence of lines and press Enter twice:\n");
|
||||
t = readLines();
|
||||
insertionSort(t);
|
||||
|
||||
wprintf(L"New sequence:\n");
|
||||
for (i = 0; t[i][0] != '\0'; i++)
|
||||
wprintf(L"%ls\n", t[i]);
|
||||
freeLines(t);
|
||||
free(t);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
typedef struct {
|
||||
wchar_t **lines;
|
||||
int lineCount;
|
||||
} Text;
|
||||
|
||||
bool readLine(wchar_t **line) {
|
||||
int i = 0, length = 1;
|
||||
wchar_t c;
|
||||
|
||||
*line = malloc(sizeof(wchar_t));
|
||||
while ((c = getwchar()) != WEOF && c != '\n') {
|
||||
if (i == length - 1) {
|
||||
length *= 2;
|
||||
*line = realloc(*line, length * sizeof(wchar_t));
|
||||
}
|
||||
(*line)[i++] = c;
|
||||
}
|
||||
(*line)[i] = '\0';
|
||||
|
||||
if (i)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void freeLines(wchar_t **lines, int i, int size) {
|
||||
while (i < size)
|
||||
free(lines[i++]);
|
||||
}
|
||||
|
||||
Text *readText() {
|
||||
Text *t = malloc(sizeof(Text));
|
||||
int i;
|
||||
|
||||
t->lines = malloc(sizeof(wchar_t *));
|
||||
t->lineCount = 1;
|
||||
for (i = 0; readLine(t->lines + i); i++) {
|
||||
if (i < t->lineCount - 1)
|
||||
continue;
|
||||
t->lineCount *= 2;
|
||||
t->lines = realloc(t->lines, t->lineCount * sizeof(wchar_t *));
|
||||
}
|
||||
|
||||
freeLines(t->lines, i, t->lineCount);
|
||||
t->lineCount = i;
|
||||
return t;
|
||||
}
|
||||
|
||||
bool compareRadix (wchar_t *a, wchar_t *b) {
|
||||
int i;
|
||||
|
||||
for (i = 0; a[i] != '\0'; i++) {
|
||||
if (a[i] > b[i] || b[i] == '\0')
|
||||
return true;
|
||||
if (a[i] < b[i])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void insertionSort(wchar_t **lines, int size) {
|
||||
int i;
|
||||
wchar_t *tmp;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
--size;
|
||||
insertionSort(lines, size);
|
||||
tmp = lines[size];
|
||||
for (i = size; i > 0 && compareRadix(lines[i - 1], tmp); i--)
|
||||
lines[i] = lines[i - 1];
|
||||
lines[i] = tmp;
|
||||
}
|
||||
|
||||
int main() {
|
||||
setlocale(LC_ALL, "pt_BR.UTF-8");
|
||||
Text *t;
|
||||
int i;
|
||||
|
||||
wprintf(L"This program orders the lines of a text in lexicographic "
|
||||
L"order.\nType in a sequence of lines and press Enter twice:\n");
|
||||
t = readText();
|
||||
insertionSort(t->lines, t->lineCount);
|
||||
|
||||
wprintf(L"New sequence:\n");
|
||||
for (i = 0; i < t->lineCount; i++)
|
||||
wprintf(L"%ls\n", t->lines[i]);
|
||||
freeLines(t->lines, 0, t->lineCount);
|
||||
free(t->lines);
|
||||
free(t);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
**2.** Sim, em ambos os casos. Isso, em função dos loops redundantes nas linhas 8 e 9, respectivamente.
|
||||
|
||||
**3.** Não. Na eventualidade de haverem valores entre $q$ e $r$ os quais não foram transcritos ao vetor $w$ na linha 7, em função de a transcrição de $p$ a $q$ já ter sido encerrada ($i == q$), estes não serão incorporados deste ponto em diante.
|
||||
|
||||
**4.** A troca é sem efeito para o resultado final, mas o desempenho do algoritmo será pior em função da adição de uma comparação desnecessária (neste caso, a comparação $v[i] > v[j]$).
|
||||
|
||||
**5.** Sim, na verdade esse é o método de comparação do qual faço uso.
|
||||
|
||||
**6.** Não, deste modo será feita a inclusão de valores de $p$ à $q$, enquanto $v[i] <= v[j]$ e, em seguida, de $q$ à $r$, enquanto $v[j] <= v[i]$, sem que a inclusão destes se dê de forma intercalada, tal qual o problema exige.
|
||||
|
||||
**7.** Este while ocorre enquanto ambas as "metades" do vetor houverem valores a serem intercalados no vetor resultante $w$ os quais ainda não foram percorridos.
|
||||
|
||||
---
|
||||
|
||||
Feitos mas não salvos **8, 9, 10**
|
||||
|
||||
---
|
||||
|
||||
**12.** Sim, ela o é. O que não seria o caso fosse feita a alteração proposta, já que os valores repetidos posteriores (depositados nos endereços de $q$ a $r$, percorridos pelo contador $j$) seriam inseridos no vetor resultante antes de suas contrapartes anteriores (depositadas nos endereços $p$ a $q$, percorridas pelo contador $i$) em função da colocação da comparação "v[i] < v[j]" na linha 6.
|
||||
|
||||
**13.** Vide arquivo `merge_lists.c`
|
||||
|
||||
## Exercícios 3
|
||||
|
||||
**1.** Ao chegarmos a linha 2, necessariamente passamos pela verificação na linha 1, então temos:
|
||||
$$
|
||||
\begin{cases} p < r - 1\ (\text I)\\ \\\ q = \dfrac{p + r}2\ (\text{II}) \end{cases}
|
||||
$$
|
||||
|
||||
Seja $f$ uma variável de "folga", $f \in \mathbb N, f \ge 1,$ tal que $p = r - 1 - f$, então
|
||||
|
||||
$$
|
||||
q = \dfrac{p + p + f + 1}2 = p + \underbrace{\dfrac{f + 1}2}_{\ge 1} \implies q > p
|
||||
$$
|
||||
|
||||
e
|
||||
|
||||
$$
|
||||
q = \dfrac{r + r - f - 1}2 = r - \underbrace{\dfrac{f + 1}2}_{\ge 1} \implies q < r
|
||||
$$
|
||||
|
||||
Logo, $p < q < r$. $\blacksquare$
|
||||
|
||||
|
||||
**2.** Ao trocarmos `(p + r) / 2` por `(p + r - 1) / 2` o vetor ao ser recursivamente subdividido e eventualmente alcançar um tamanho $r - p = 2$ teremos, em função da divisão inteira:
|
||||
|
||||
$$
|
||||
\displaystyle q = \frac{p + r - 1}2 = \frac{2p + 2 - 1}2 = p + \underbrace{\frac 12}_{= 0} = p
|
||||
$$
|
||||
|
||||
Assim, nas duas próximas chamadas ao mergesort, teremos algo equivalente à `mergesort(p, p, v)` o que compreende nenhum elemento e `mergesort(p, r, v)`, o que compreende os mesmos dois elementos da atual invocação. Ou seja, temos uma recursão infinita. $\square$
|
||||
|
||||
A mesma situação não se observa para `(p + r + 1) / 2`. Seja $r = p + \text{tam}, \text{tam} \ge 2$ então
|
||||
|
||||
$$
|
||||
\displaystyle q = \frac{p + r + 1}2 = \frac{2p + \text{tam} + 1}2 = p + \underbrace{\frac{\text{tam} + 1}2}_{\ge 1} \therefore p < q < r
|
||||
$$
|
||||
|
||||
Assim, o vetor será sempre repartido em uma posição intermediária aos seus elementos, o que conduzirá o algoritmo a sua resolução. $\blacksquare$
|
||||
|
||||
**3.**
|
||||
```c
|
||||
mergesort(1,4, v)
|
||||
mergesort(1,2, v)
|
||||
mergesort(1,1, v)
|
||||
mergesort(2,2, v)
|
||||
mergesort(3,4, v)
|
||||
mergesort(3,3, v)
|
||||
mergesort(4,4, v)
|
||||
```
|
||||
|
||||
**4.**
|
||||
```c
|
||||
void mergeSort (array A, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = size / 2;
|
||||
mergeSort(A, pivot);
|
||||
mergeSort(A + pivot, size - pivot)
|
||||
merge(A, pivot, size);
|
||||
}
|
||||
```
|
||||
|
||||
Temos que o tamanho do vetor é sempre maior que 1, e assim o pivô sempre assume um valor intermediário entre o tamanho do vetor (ou subvetor) e o início deste, subdividindo-o, (em porções menores até se alcançar o tamanho 1) e a intercalação de vetores é possível.
|
||||
|
||||
**5.** Sim ela o é tendo em vista que a comparação entre os elementos presentes no primeiro e segundo subvetores se dá por $A[i] <= A[j]$, onde $i < j$, o valor equivalente que se apresenta primeiro é inserido, também primeiramente, no vetor resultante.
|
||||
|
||||
**6.** Pode-se fazer uso da solução que apresentei anteriormente, no exercício quatro, fazendo-se uso de um único numerador.
|
||||
|
||||
**7.** Feito conforme exigência da disciplina de Introdução a Análise de Algoritmos.
|
||||
|
||||
## Exercícios 4
|
||||
|
||||
**1.** Não está correto pois o pivô foi deslocado em uma posição (`q + 1`) ao passá-lo a função intercala. Isso fará que o menor valor do segundo subvetor seja incluído no vetor resultante apenas após todos os valores do primeiro subvetor terem sido incluídos neste, o que pode incluir valores maiores que este. Por exemplo, para $1\ 3\ 5\ |\ 2\ 4\ 6$ teríamos um vetor resultante: $1\ 3\ 4\ 5\ 2\ 6$.
|
||||
|
||||
**2.** Não. Quando o subvetor alcança tamanho 1, este é subdivido em um subvetor de tamanho 0 e mais outro de tamanho 1, e assim indefinidamente.
|
||||
|
||||
**3.** Não, falamos sobre isso no exercício 2 do bloco anterior (3).
|
||||
|
||||
**4.** Não em ambos os casos. Para um vetor de tamanho 2 temos que $q = 0$, gerando dois vetores: um de tamanho nulo e outro de tamanho 2; e assim indefinidamente.
|
||||
|
||||
**5.** Definitivamente não. Podemos fazer uma demonstração de caso com o vetor $1\ 3\ 5\ 2\ 4\ 6$ para atestarmos isso. Este não será intercalado corretamente.
|
||||
|
||||
**6.** Sim, mas muito mais lentamente, em tempo quadrático.
|
||||
|
||||
**7, 8.** Feito.
|
||||
|
||||
## Exercícios 5
|
||||
|
||||
**1.**
|
||||
```c
|
||||
int c = 1 ← T(1)
|
||||
for (int i = 0; i < n; i *=2) ← T(n/2)
|
||||
for (int j = 1; j < n; j++) ← T(n)
|
||||
c += 1; ← T(1)
|
||||
```
|
||||
|
||||
O tempo de execução em função de n é, portanto
|
||||
|
||||
$$
|
||||
T \left(1 + n \cdot \frac n2 \cdot 1 \right) = T \left(\frac{n^2}2 + 1 \right)
|
||||
$$
|
||||
|
||||
**2.** Feito no
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#include "./merge_shell_sort.c"
|
||||
#include <limits.h>
|
||||
|
||||
int main () {
|
||||
int i = 0, size, index;
|
||||
array A;
|
||||
|
||||
if (!scanf(" %d", &size) || size < 1 || size > INT_MAX) {
|
||||
printf("Tamanho inválido: não se encontra desde 1 a %d.\n", INT_MAX);
|
||||
return 1;
|
||||
}
|
||||
A = malloc(size * sizeof(int));
|
||||
while (i < size && scanf(" %d", A + i))
|
||||
i++;
|
||||
if (i < size) {
|
||||
printf("Lista mal formatada: apenas %d valores foram encontrados.\n", i);
|
||||
return 1;
|
||||
}
|
||||
if (!scanf(" %d", &index) || index < 1 || index >= size) {
|
||||
printf("Índice invalido: não se encontra desde 1 a %d.\n", size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
mergeSort(A, size);
|
||||
printf("O %dº elemento de menor valor: %d\n", index, A[index - 1]);
|
||||
free(A);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
void merge (array A, array tmp, int pivot, int size) {
|
||||
int i, k, j = pivot;
|
||||
|
||||
for (i = k = 0; k < size; k++)
|
||||
tmp[k] = (j == size || (i < pivot && A[i] >= A[j])) ?
|
||||
A[i++] : A[j++];
|
||||
for (k = 0; k < size; k++)
|
||||
A[k] = tmp[k];
|
||||
|
||||
}
|
||||
|
||||
void mergeSort (array A, array tmp, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = size / 2;
|
||||
mergeSort(A, tmp, pivot);
|
||||
mergeSort(A + pivot, tmp + pivot, size - pivot);
|
||||
merge(A, tmp, pivot, size);
|
||||
}
|
||||
|
||||
void sort (array A, int size) {
|
||||
array tmp = malloc(size * sizeof(int));
|
||||
mergeSort(A, tmp, size);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf("%d", A + i))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
i++;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs a merge sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
sort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define Array int *
|
||||
|
||||
Array readArray(int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
Array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
void interleave(Array A, int pivot, int size) {
|
||||
int i, tmp = A[pivot];
|
||||
|
||||
if (pivot == size)
|
||||
return;
|
||||
for (i = pivot; i > 0 && A[i - 1] > tmp; i--)
|
||||
A[i] = A[i - 1];
|
||||
A[i] = tmp;
|
||||
interleave(A, pivot + 1, size);
|
||||
}
|
||||
|
||||
void mergeSort(Array A, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = size / 2;
|
||||
mergeSort(A, pivot);
|
||||
mergeSort(A + pivot, size - pivot);
|
||||
interleave(A, pivot, size);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs an in-place merge sort.\nType in a sequence "
|
||||
"of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
mergeSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int key;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
Node * readList() {
|
||||
int key;
|
||||
char c;
|
||||
Node *HEAD, *current, *prev;
|
||||
|
||||
printf("\nType in a sequence of ascending integer values separated by spaces"
|
||||
"and press ENTER:\n");
|
||||
|
||||
if (!scanf(" %d", &key))
|
||||
return NULL;
|
||||
HEAD = malloc(sizeof(Node));
|
||||
HEAD->key = key;
|
||||
prev = HEAD;
|
||||
current = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n') {
|
||||
if (!scanf("%d", &key))
|
||||
break;
|
||||
current = malloc(sizeof(Node));
|
||||
current->key = key;
|
||||
prev->next = current;
|
||||
prev = current;
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->next = NULL;
|
||||
else
|
||||
HEAD->next = NULL;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
Node * mergeLists (Node *a, Node *b) {
|
||||
if (!a && !b)
|
||||
return NULL;
|
||||
if (a) {
|
||||
if (!b)
|
||||
return a;
|
||||
if (a->key <= b->key) {
|
||||
a->next = mergeLists (a->next, b);
|
||||
return a;
|
||||
}
|
||||
b->next = mergeLists (a, b->next);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void printList(Node *n) {
|
||||
printf("\nNew sequence:\n");
|
||||
while (n) {
|
||||
printf("%d ", n->key);
|
||||
n = n->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main () {
|
||||
printf("This program merges two linked lists with keys in ascending order."
|
||||
"\n");
|
||||
printList(mergeLists(readList(), readList()));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
/* Shell sort */
|
||||
|
||||
void insertionSort (array A, int size, int start, int gap) {
|
||||
int i = start + gap, tmp;
|
||||
|
||||
if (i >= size)
|
||||
return;
|
||||
tmp = A[i];
|
||||
while (i >= gap && A[i - gap] > tmp) {
|
||||
A[i] = A[i - gap];
|
||||
i-= gap;
|
||||
}
|
||||
A[i] = tmp;
|
||||
insertionSort(A, size, start + gap, gap);
|
||||
}
|
||||
|
||||
void shellSort (array A, int size) {
|
||||
int i, sublist_lenght;
|
||||
|
||||
for (sublist_lenght = size /2; sublist_lenght > 0; sublist_lenght /= 2)
|
||||
for (i = 0; i < sublist_lenght; i++)
|
||||
insertionSort(A, size, i, sublist_lenght);
|
||||
}
|
||||
|
||||
/* Merge Sort */
|
||||
|
||||
void merge (array A, int pivot, int size) {
|
||||
int i, k, j = pivot;
|
||||
array tmp = malloc(size * sizeof(int));
|
||||
|
||||
for (i = k = 0; k < size; k++)
|
||||
tmp[k] = (j == size || (i < pivot && A[i] <= A[j])) ?
|
||||
A[i++] : A[j++];
|
||||
for (k = 0; k < size; k++)
|
||||
A[k] = tmp[k];
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
void mergeSort (array A, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
if (size <= 10)
|
||||
shellSort(A, size);
|
||||
else {
|
||||
pivot = size / 2;
|
||||
mergeSort(A, pivot);
|
||||
mergeSort(A + pivot, size - pivot);
|
||||
merge(A, pivot, size);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
void merge (array A, int pivot, int size) {
|
||||
int i, k, j = pivot;
|
||||
array tmp = malloc(size * sizeof(int));
|
||||
|
||||
for (i = k = 0; k < size; k++)
|
||||
tmp[k] = (j == size || (i < pivot && A[i] <= A[j])) ?
|
||||
A[i++] : A[j++];
|
||||
for (k = 0; k < size; k++)
|
||||
A[k] = tmp[k];
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
void mergeSort (array A, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = (size + 1)/ 2;
|
||||
mergeSort(A, pivot);
|
||||
mergeSort(A + pivot, size - pivot);
|
||||
merge(A, pivot, size);
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf("%d", &A[i]))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
i++;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs an insertion sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
mergeSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define array int *
|
||||
|
||||
typedef struct node {
|
||||
int key;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
Node *newNode(int key) {
|
||||
Node *new = malloc(sizeof(Node));
|
||||
new->key = key;
|
||||
return new;
|
||||
}
|
||||
|
||||
Node *read() {
|
||||
int key;
|
||||
char c;
|
||||
Node *HEAD, *current, *prev;
|
||||
|
||||
if (!scanf(" %d", &key))
|
||||
return NULL;
|
||||
HEAD = newNode(key);
|
||||
prev = HEAD;
|
||||
current = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
|
||||
current = newNode(key);
|
||||
prev->next = current;
|
||||
prev = current;
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->next = NULL;
|
||||
else
|
||||
HEAD->next = NULL;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
Node *mid(Node *slow) {
|
||||
Node *fast = slow->next;
|
||||
|
||||
while (fast && (fast = fast->next)) {
|
||||
fast = fast->next;
|
||||
slow = slow->next;
|
||||
}
|
||||
fast = slow->next;
|
||||
slow->next = NULL;
|
||||
return fast;
|
||||
}
|
||||
|
||||
Node *merge(Node *a, Node *b) {
|
||||
if (a) {
|
||||
if (!b)
|
||||
return a;
|
||||
if (a->key <= b->key) {
|
||||
a->next = merge(a->next, b);
|
||||
return a;
|
||||
}
|
||||
b->next = merge(a, b->next);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
Node *mergeSort(Node *n) {
|
||||
return (n) ? merge(mergeSort(n), mergeSort(mid(n))) : n;
|
||||
}
|
||||
|
||||
void printList(Node *n) {
|
||||
printf("\nNew sequence:\n");
|
||||
while (n) {
|
||||
printf("%d ", n->key);
|
||||
n = n->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("This program sorts a linked list based on its nodes' keys values."
|
||||
"\nType in a sequence of integer values separated by spaces and "
|
||||
"press ENTER: ");
|
||||
printList(mergeSort(read()));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#define array int*
|
||||
|
||||
void merge (array A, array tmp, int pivot, int size) {
|
||||
int i, k, j = pivot;
|
||||
|
||||
for (i = k = 0; k < size; k++)
|
||||
tmp[k] = (j == size || (i < pivot && A[i] <= A[j])) ?
|
||||
A[i++] : A[j++];
|
||||
for (k = 0; k < size; k++)
|
||||
A[k] = tmp[k];
|
||||
|
||||
}
|
||||
|
||||
void mergeSort (array A, array tmp, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = size / 2;
|
||||
mergeSort(A, tmp, pivot);
|
||||
mergeSort(A + pivot, tmp + pivot, size - pivot);
|
||||
merge(A, tmp, pivot, size);
|
||||
}
|
||||
|
||||
void sort (array A, int size) {
|
||||
array tmp = malloc(size * sizeof(int));
|
||||
mergeSort(A, tmp, size);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
array readArray (int *size) {
|
||||
int i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf("%d", A + i))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
i++;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs a merge sort.\nType in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
sort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define array int *
|
||||
|
||||
void merge(array A, int pivot, int size) {
|
||||
int i = 0, j = size - 1, k;
|
||||
array tmp = malloc(size * sizeof(int));
|
||||
|
||||
while (i < pivot) {
|
||||
tmp[i] = A[i];
|
||||
i++;
|
||||
}
|
||||
while (i < size) {
|
||||
tmp[i] = A[j - (i - pivot)];
|
||||
i++;
|
||||
}
|
||||
for (i = k = 0; k < size; k++)
|
||||
A[k] = (tmp[i] <= tmp[j]) ? tmp[i++] : tmp[j--];
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
void mergeSort(array A, int size) {
|
||||
int pivot;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
pivot = size / 2;
|
||||
mergeSort(A, pivot);
|
||||
mergeSort(A + pivot, size - pivot);
|
||||
merge(A, pivot, size);
|
||||
}
|
||||
|
||||
array readArray(int *size) {
|
||||
int i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf("%d", A + i))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
i++;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int main() {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs a merge sort.\nType in a sequence of values "
|
||||
"separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
mergeSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
# Respostas aos exercícios
|
||||
|
||||
## Exercícios 2
|
||||
|
||||
**4.** Conforme a seguinte implementação
|
||||
|
||||
```c
|
||||
01 | static int separa (int v[], int p, int r) {
|
||||
02 | int c = v[r]; //pivô
|
||||
03 | int t, j = p;
|
||||
04 | for (int k = p; k < r; k++) {
|
||||
05 | if (v[k] <= c) {
|
||||
06 | t = v[j];
|
||||
07 | v[j] = v[k];
|
||||
08 | v[k] = t;
|
||||
09 | j++;
|
||||
10 | }
|
||||
11 | t = v[j];
|
||||
12 | v[j] = v[r];
|
||||
13 | v[r] = t;
|
||||
14 | }
|
||||
15 | }
|
||||
```
|
||||
|
||||
Verifiquemos se os seguintes invariantes são verdadeiros:
|
||||
|
||||
1. $p \le j \le k$
|
||||
|
||||
O valor de $j$ é tido inicialmente na linha 03 como sendo igual a $p$, equivalente portanto também à $k$ tal qual este último é definido na linha 04. Para cada iteração da repetição `for` o valor de $k$ é incrementado, enquanto o valor de j neste mesmo loop é incrementado se, e somente se, a comparação posta pela linha 05 é tida verdadeira.
|
||||
|
||||
Sendo este o único ponto no algoritmo em que o valor de j é modificado tem-se que j pode assumir valores tais que $p \le j \le k$ apenas. $\blacksquare$
|
||||
|
||||
2. $v[p \dots j - 1] \le c$
|
||||
|
||||
Inicialmente, $j = p$, então $v[p \dots j - 1]$ compreende um conjunto vazio. Feita a primeira iteração, tem-se a manutenção do invariante para compreender o primeiro elemento da lista que, para a iteração seguinte, corresponde à posição `j - 1`. O mesmo processo se repete para cada repetição subsequente. $\blacksquare$
|
||||
|
||||
3. $v[j \dots k - 1] > c$
|
||||
|
||||
Inicialmente, $k = p$ e $j = p$, então $v[j \dots k - 1]$ compreende um conjunto vazio. Feita a primeira iteração, tem-se a manutenção do invariante para compreender o primeiro elemento da lista que, para a iteração seguinte, corresponde à posição `k - 1`. Se este for menor ou igual a $c$, $j = k$ e $v[j \dots k - 1]$ continua vazio. Senão, $j = k - 1$ e $v[j \dots k - 1]$ compreende mais este valor. O mesmo processo se repete para cada repetição subsequente. $\blacksquare$
|
||||
|
||||
4. $v[p \dots r]$ é uma permutação do vetor original.
|
||||
|
||||
O quickSort é um algoritmo de ordenação o qual não faz uso de memória auxiliar. Suas operações são feitas com base em substituições (linhas 6 à 13) sobre o vetor original. Assim o sendo, segue que o resultado desta operação produz, a cada etapa, uma permutação deste vetor.
|
||||
|
||||
**7.** Não. Isso pois o elemento aquele selecionado enquanto pivô é *sempre* posicionado no vetor ao final do processo de partição após valores maiores ou iguais a ele. Isso, ainda que ele possa ter figurado antes doutros elementos de mesmo valor.
|
||||
|
||||
## Exercícios 3
|
||||
|
||||
```
|
||||
quicksort (v, 1, 6)
|
||||
quicksort (v, 1, 2)
|
||||
quicksort (v, 1, 0)
|
||||
quicksort (v, 2, 2)
|
||||
quicksort (v, 4, 6)
|
||||
quicksort (v, 4, 4)
|
||||
quicksort (v, 6, 6)
|
||||
```
|
|
@ -0,0 +1,52 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int *readArray(int *size) {
|
||||
int i = 0;
|
||||
char c;
|
||||
int *A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", A + i))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
i++;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
void swap(int *a, int *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
void partition(int *v, int size) {
|
||||
int i, j;
|
||||
|
||||
for (i = j = 0; i < size; i++)
|
||||
if (v[i] == 0)
|
||||
swap(&v[i], &v[j++]);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int *A;
|
||||
int i, size;
|
||||
|
||||
printf("This program sorts an array of 0s and 1s in crescent order.\nType "
|
||||
"in a sequence of values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
partition(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct node{
|
||||
int key;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
Node * newNode (int key) {
|
||||
Node * new = malloc(sizeof(Node));
|
||||
new->key = key;
|
||||
return new;
|
||||
}
|
||||
|
||||
Node * read() {
|
||||
int key;
|
||||
char c;
|
||||
Node *HEAD, *current, *prev;
|
||||
|
||||
if (!scanf(" %d", &key))
|
||||
return NULL;
|
||||
HEAD = newNode(key);
|
||||
prev = HEAD;
|
||||
current = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
|
||||
current = newNode(key);
|
||||
prev->next = current;
|
||||
prev = current;
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->next = NULL;
|
||||
else
|
||||
HEAD->next = NULL;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
Node * median (Node *start) {
|
||||
Node *slow = start->next, *fast = slow->next;
|
||||
|
||||
if (!fast)
|
||||
return slow;
|
||||
while (fast->next && fast->next->next) {
|
||||
fast = fast->next->next;
|
||||
slow = slow->next;
|
||||
}
|
||||
if ((start->key > slow->key) ^ (start->key > fast->key))
|
||||
return start;
|
||||
if ((slow->key < start->key) ^ (slow->key < fast->key))
|
||||
return slow;
|
||||
return fast;
|
||||
}
|
||||
|
||||
void partition (Node *n, Node *pivot, Node **le, Node **gt) {
|
||||
if (!n)
|
||||
*le = *gt = NULL;
|
||||
else if (n == pivot)
|
||||
partition(n->next, pivot, le, gt);
|
||||
else if (n->key <= pivot->key) {
|
||||
*le = n;
|
||||
partition(n->next, pivot, &n->next, gt);
|
||||
}
|
||||
else {
|
||||
*gt = n;
|
||||
partition(n->next, pivot, le, &n->next);
|
||||
}
|
||||
}
|
||||
|
||||
Node * append (Node *le, Node *pivot, Node *gt) {
|
||||
if (le) {
|
||||
le->next = append(le->next, pivot, gt);
|
||||
return le;
|
||||
}
|
||||
pivot->next = gt;
|
||||
return pivot;
|
||||
}
|
||||
|
||||
Node * quickSort (Node * HEAD) {
|
||||
Node *le, *gt, *pivot;
|
||||
|
||||
if (!HEAD || !HEAD->next)
|
||||
return HEAD;
|
||||
pivot = median(HEAD);
|
||||
partition(HEAD, pivot, &le, >);
|
||||
return append(quickSort(le), pivot, quickSort(gt));
|
||||
}
|
||||
|
||||
void printList(Node *n) {
|
||||
printf("\nNew sequence:\n");
|
||||
while (n) {
|
||||
printf("%d ", n->key);
|
||||
n = n->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main () {
|
||||
printf("This program sorts a linked list based on its nodes' keys values."
|
||||
"\nType in a sequence of integer values separated by spaces and "
|
||||
"press ENTER: ");
|
||||
printList(quickSort(read()));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define array int*
|
||||
|
||||
array readArray (int *size) {
|
||||
int i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &A[i]))
|
||||
continue;
|
||||
if (i++ == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
void swap (int *a, int *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
void partition (array A, int size) {
|
||||
int i, j;
|
||||
|
||||
for (i = j = 0; i < size; i++)
|
||||
if (A[i] < 0)
|
||||
swap(&A[i], &A[j++]);
|
||||
}
|
||||
|
||||
int main () {
|
||||
array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs a partition of a list of integer values.\n"
|
||||
"Type in a sequence of values separated by spaces and press ENTER:\n");
|
||||
A = readArray(&size);
|
||||
partition(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct node{
|
||||
int key;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
Node * newNode (int key) {
|
||||
Node * new = malloc(sizeof(Node));
|
||||
new->key = key;
|
||||
return new;
|
||||
}
|
||||
|
||||
Node * read() {
|
||||
int key;
|
||||
char c;
|
||||
Node *HEAD, *current, *prev;
|
||||
|
||||
if (!scanf(" %d", &key))
|
||||
return NULL;
|
||||
HEAD = newNode(key);
|
||||
prev = HEAD;
|
||||
current = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
|
||||
current = newNode(key);
|
||||
prev->next = current;
|
||||
prev = current;
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->next = NULL;
|
||||
else
|
||||
HEAD->next = NULL;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
void partition (Node *n, Node **pairs, Node **odds) {
|
||||
if (!n)
|
||||
*pairs = *odds = NULL;
|
||||
else if (n->key % 2 == 0) {
|
||||
*pairs = n;
|
||||
partition(n->next, &n->next, odds);
|
||||
}
|
||||
else {
|
||||
*odds = n;
|
||||
partition(n->next, pairs, &n->next);
|
||||
}
|
||||
}
|
||||
|
||||
void printList(Node *n) {
|
||||
while (n) {
|
||||
printf("%d ", n->key);
|
||||
n = n->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main () {
|
||||
Node *pairs, *odds;
|
||||
|
||||
printf("This program partitions a linked list into two, onde containing "
|
||||
"all nodes with pair values and another containing other nodes.\n"
|
||||
"Type in a sequence of integer values separated by spaces and "
|
||||
"press ENTER:\n");
|
||||
|
||||
partition(read(), &pairs, &odds);
|
||||
|
||||
printf("\nPair values:\n");
|
||||
printList(pairs);
|
||||
|
||||
printf("\nOdd values:\n");
|
||||
printList(odds);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define Array int *
|
||||
|
||||
Array readArray(int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
Array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
void swap(int *a, int *b) {
|
||||
int tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
void heapify(Array A, int size, int i) {
|
||||
int min = i, left = 2 * min + 1, right = left + 1;
|
||||
|
||||
if (left >= size)
|
||||
return;
|
||||
if (A[left] < A[min])
|
||||
min = left;
|
||||
if (right < size && A[right] < A[min])
|
||||
min = right;
|
||||
else if (min == i)
|
||||
return;
|
||||
|
||||
swap(A + i, A + min);
|
||||
heapify(A, size, min);
|
||||
}
|
||||
|
||||
void heapSort(Array A, int size) {
|
||||
int i;
|
||||
|
||||
if (size <= 1)
|
||||
return;
|
||||
|
||||
for (i = (size - 1) / 2; i <= 0; i--)
|
||||
heapify(A, size, i);
|
||||
|
||||
for (i = size - 1; i > 0; i--) {
|
||||
swap(A, A + i);
|
||||
heapify(A, i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
Array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program uses a min heap to sort integers in crecreasing "
|
||||
"order.\nType in a sequence of values separated by spaces and press "
|
||||
"ENTER: ");
|
||||
A = readArray(&size);
|
||||
heapSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define Array int *
|
||||
|
||||
Array readArray(int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
Array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int pivot(Array A, int size, int mask) {
|
||||
int i, pivot;
|
||||
|
||||
for (i = pivot = 0; i < size; i++)
|
||||
if ((A[i] & mask) == 0)
|
||||
pivot++;
|
||||
return pivot;
|
||||
}
|
||||
|
||||
Array countingSort(Array A, int size, int mask) {
|
||||
int i, j = pivot(A, size, mask), k;
|
||||
Array sorted;
|
||||
|
||||
if (!j || j == size)
|
||||
return A;
|
||||
|
||||
sorted = malloc(size * sizeof(int));
|
||||
for (i = k = 0; k < size; k++)
|
||||
if (A[k] & mask)
|
||||
sorted[j++] = A[k];
|
||||
else
|
||||
sorted[i++] = A[k];
|
||||
free(A);
|
||||
return sorted;
|
||||
}
|
||||
|
||||
Array radixSort(Array A, int size) {
|
||||
int mask;
|
||||
|
||||
for (mask = 1; mask; mask <<= 1)
|
||||
A = countingSort(A, size, mask);
|
||||
return A;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs a binary radix sort.\nType in a sequence "
|
||||
"of integer values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
A = radixSort(A, size);
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define Array int *
|
||||
|
||||
Array readArray(int *size) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
Array A;
|
||||
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
int max(Array a, int size) {
|
||||
int i, max = *a;
|
||||
|
||||
for (i = 1; i < size; i++)
|
||||
if (a[i] > max)
|
||||
max = a[i];
|
||||
return max;
|
||||
}
|
||||
|
||||
int bits(int n) { return (n >>= 1) ? 1 + bits(n) : 0; }
|
||||
|
||||
int pivot(Array A, int size, unsigned int mask) {
|
||||
int i, pivot;
|
||||
|
||||
for (i = pivot = 0; i < size; i++)
|
||||
if ((A[i] & mask) == 0)
|
||||
pivot++;
|
||||
return pivot;
|
||||
}
|
||||
|
||||
Array append(Array a, Array b, int p, int size) {
|
||||
int i, *result = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < p; i++)
|
||||
result[i] = a[i];
|
||||
while (i < size) {
|
||||
result[i] = b[i - p];
|
||||
i++;
|
||||
}
|
||||
free(a);
|
||||
free(b);
|
||||
return result;
|
||||
}
|
||||
|
||||
void distribute(Array A, Array zeroes, Array ones, int mask, int size) {
|
||||
if (size <= 0)
|
||||
return;
|
||||
if (*A & mask) {
|
||||
*ones = *A;
|
||||
ones += 1;
|
||||
} else {
|
||||
*zeroes = *A;
|
||||
zeroes += 1;
|
||||
}
|
||||
distribute(A + 1, zeroes, ones, mask, size - 1);
|
||||
}
|
||||
|
||||
Array radixSort(Array A, int size, unsigned int mask) {
|
||||
int p, *zeroes, *ones;
|
||||
|
||||
if (!mask || size <= 1)
|
||||
return A;
|
||||
|
||||
p = pivot(A, size, mask);
|
||||
|
||||
if (!p || p == size)
|
||||
return radixSort(A, size, mask >> 1);
|
||||
|
||||
zeroes = malloc(p * sizeof(int));
|
||||
ones = malloc((size - p) * sizeof(int));
|
||||
|
||||
distribute(A, zeroes, ones, mask, size);
|
||||
free(A);
|
||||
|
||||
zeroes = radixSort(zeroes, p, mask >> 1);
|
||||
ones = radixSort(ones, size - p, mask >> 1);
|
||||
return append(zeroes, ones, p, size);
|
||||
}
|
||||
|
||||
int main() {
|
||||
Array A;
|
||||
int i, size;
|
||||
|
||||
printf("This program performs a binary radix sort.\nType in a sequence "
|
||||
"of integer values separated by spaces and press ENTER: ");
|
||||
A = readArray(&size);
|
||||
A = radixSort(A, size, 1 << bits(max(A, size)));
|
||||
|
||||
printf("New sequence:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define array int *
|
||||
|
||||
typedef struct node {
|
||||
int key;
|
||||
struct node *next;
|
||||
} List;
|
||||
|
||||
List *newList(int key, List *next) {
|
||||
List *new = malloc(sizeof(List));
|
||||
new->key = key;
|
||||
new->next = next;
|
||||
return new;
|
||||
}
|
||||
|
||||
List *read() {
|
||||
int key;
|
||||
char c;
|
||||
List *HEAD, *current, *prev;
|
||||
|
||||
if (!scanf(" %d", &key))
|
||||
return NULL;
|
||||
HEAD = newList(key, NULL);
|
||||
prev = HEAD;
|
||||
current = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
|
||||
current = newList(key, NULL);
|
||||
prev->next = current;
|
||||
prev = current;
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->next = NULL;
|
||||
else
|
||||
HEAD->next = NULL;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
void printList(List *n) {
|
||||
printf("\nNew sequence:\n");
|
||||
while (n) {
|
||||
printf("%d ", n->key);
|
||||
n = n->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
List *append(List *a, List *pivot, List *b) {
|
||||
pivot->next = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
List *headless(List *l) {
|
||||
List *next = l->next;
|
||||
free(l);
|
||||
return next;
|
||||
}
|
||||
|
||||
List *partition(List *l, List *zeroes, List *ones, int mask) {
|
||||
while (l) {
|
||||
if (l->key & mask) {
|
||||
ones->next = l;
|
||||
ones = ones->next;
|
||||
} else {
|
||||
zeroes->next = l;
|
||||
zeroes = zeroes->next;
|
||||
}
|
||||
l = l->next;
|
||||
}
|
||||
ones->next = NULL;
|
||||
return zeroes;
|
||||
}
|
||||
|
||||
List *countingSort(List *l, int mask) {
|
||||
List *zeroes = newList(0, NULL), *ones = newList(1, NULL),
|
||||
*pivot = partition(l, zeroes, ones, mask);
|
||||
|
||||
zeroes = headless(zeroes);
|
||||
ones = headless(ones);
|
||||
|
||||
return (zeroes && ones) ? append(zeroes, pivot, ones) : l;
|
||||
}
|
||||
|
||||
List *radixSort(List *l) {
|
||||
int mask;
|
||||
|
||||
if (l)
|
||||
for (mask = 1; mask; mask <<= 1)
|
||||
l = countingSort(l, mask);
|
||||
return l;
|
||||
}
|
||||
|
||||
int main() {
|
||||
printf("This program sorts a linked list based on its nodes' keys values."
|
||||
"\nType in a sequence of integer values separated by spaces and "
|
||||
"press ENTER: ");
|
||||
printList(radixSort(read()));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define array int *
|
||||
|
||||
typedef struct node {
|
||||
int key;
|
||||
struct node *next;
|
||||
} List;
|
||||
|
||||
List *newList(int key, List *next) {
|
||||
List *new = malloc(sizeof(List));
|
||||
new->key = key;
|
||||
new->next = next;
|
||||
return new;
|
||||
}
|
||||
|
||||
List *read() {
|
||||
int key;
|
||||
char c;
|
||||
List *HEAD, *current, *prev;
|
||||
|
||||
if (!scanf(" %d", &key))
|
||||
return NULL;
|
||||
HEAD = newList(key, NULL);
|
||||
prev = HEAD;
|
||||
current = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key)) {
|
||||
current = newList(key, NULL);
|
||||
prev->next = current;
|
||||
prev = current;
|
||||
}
|
||||
|
||||
if (current)
|
||||
current->next = NULL;
|
||||
else
|
||||
HEAD->next = NULL;
|
||||
return HEAD;
|
||||
}
|
||||
|
||||
void printList(List *n) {
|
||||
printf("\nNew sequence:\n");
|
||||
while (n) {
|
||||
printf("%d ", n->key);
|
||||
n = n->next;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int max(List *l) {
|
||||
int max = l->key;
|
||||
for (l = l->next; l; l = l->next)
|
||||
if (l->key > max)
|
||||
max = l->key;
|
||||
return max;
|
||||
}
|
||||
|
||||
int bits(int n) { return (n >>= 1) ? 1 + bits(n) : 0; }
|
||||
|
||||
List *append(List *a, List *b) {
|
||||
while (a->next)
|
||||
a = a->next;
|
||||
a->next = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
List *headless(List *l) {
|
||||
List *next = l->next;
|
||||
free(l);
|
||||
return next;
|
||||
}
|
||||
|
||||
void partition(List *l, List *zeroes, List *ones, int mask) {
|
||||
while (l) {
|
||||
if (l->key & mask) {
|
||||
ones->next = l;
|
||||
ones = ones->next;
|
||||
} else {
|
||||
zeroes->next = l;
|
||||
zeroes = zeroes->next;
|
||||
}
|
||||
l = l->next;
|
||||
}
|
||||
zeroes->next = ones->next = NULL;
|
||||
}
|
||||
|
||||
List *radixSort(List *l, unsigned int mask) {
|
||||
List *zeroes, *ones;
|
||||
|
||||
if (!l->next || !mask)
|
||||
return l;
|
||||
zeroes = newList(0, NULL);
|
||||
ones = newList(1, NULL);
|
||||
partition(l, zeroes, ones, mask);
|
||||
zeroes = headless(zeroes);
|
||||
ones = headless(ones);
|
||||
|
||||
if (!zeroes || !ones)
|
||||
return l;
|
||||
|
||||
zeroes = radixSort(zeroes, mask >> 1);
|
||||
ones = radixSort(ones, mask >> 1);
|
||||
return append(zeroes, ones);
|
||||
}
|
||||
|
||||
int main() {
|
||||
List *l;
|
||||
printf("This program sorts a linked list based on its nodes' keys values."
|
||||
"\nType in a sequence of integer values separated by spaces and "
|
||||
"press ENTER: ");
|
||||
l = read();
|
||||
printList(radixSort(l, 1 << bits(max(l))));
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
typedef struct node{
|
||||
int key, height;
|
||||
struct node *lt, *gt;
|
||||
} Node;
|
||||
|
||||
/* Tree balancing */
|
||||
|
||||
int height (Node *root) {
|
||||
return (root) ? root->height : -1;
|
||||
}
|
||||
|
||||
int getBalance (Node *root) {
|
||||
return height(root->lt) - height(root->gt);
|
||||
}
|
||||
|
||||
void updateHeight (Node *root) {
|
||||
root->height = MAX(height(root->lt), height(root->gt)) + 1;
|
||||
}
|
||||
|
||||
Node * rotateLeft (Node *root) {
|
||||
Node *newRoot = root->gt, *child = newRoot->lt;
|
||||
|
||||
newRoot->lt = root;
|
||||
root->gt = child;
|
||||
|
||||
updateHeight(root);
|
||||
updateHeight(newRoot);
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
Node * rotateRight (Node *root) {
|
||||
Node *newRoot = root->lt, *child = newRoot->gt;
|
||||
|
||||
newRoot->gt = root;
|
||||
root->lt = child;
|
||||
|
||||
updateHeight(root);
|
||||
updateHeight(newRoot);
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
Node * balanceTree (Node *root) {
|
||||
int balance = getBalance(root);
|
||||
|
||||
/* Left heavy */
|
||||
if (balance > 1) {
|
||||
if (getBalance(root->lt) < 0)
|
||||
root->lt = rotateLeft(root->lt);
|
||||
return rotateRight(root);
|
||||
}
|
||||
|
||||
/* Right heavy */
|
||||
if (balance < -1) {
|
||||
if (getBalance(root->gt) > 0)
|
||||
root->gt = rotateRight(root->gt);
|
||||
return rotateLeft(root);
|
||||
}
|
||||
|
||||
updateHeight(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
/* Node insertion */
|
||||
|
||||
Node * newNode(int key){
|
||||
Node *new = malloc(sizeof(Node));
|
||||
|
||||
new->key = key;
|
||||
new->height = 0;
|
||||
new->lt = new->gt = NULL;
|
||||
return new;
|
||||
}
|
||||
|
||||
bool insertNode(Node **root, int key) {
|
||||
Node **n;
|
||||
|
||||
if (!*root) {
|
||||
*root = newNode(key);
|
||||
return true;
|
||||
}
|
||||
if (key == (*root)->key)
|
||||
return false;
|
||||
n = (key < (*root)->key) ? &(*root)->lt : &(*root)->gt;
|
||||
if (!insertNode(n, key))
|
||||
return false;
|
||||
*root = balanceTree(*root);
|
||||
return true;
|
||||
}
|
||||
|
||||
Node * read() {
|
||||
int key;
|
||||
char c;
|
||||
Node *root = NULL;
|
||||
|
||||
while ((c = getchar()) != EOF && c != '\n' && scanf("%d", &key))
|
||||
insertNode(&root, key);
|
||||
return root;
|
||||
}
|
||||
|
||||
/* Find next */
|
||||
|
||||
Node * nextKey (Node * root, int key) {
|
||||
Node *n;
|
||||
|
||||
if (!root)
|
||||
return root;
|
||||
n = nextKey((key < root->key) ? root->lt : root->gt, key);
|
||||
return (n && n->key > key) ? n : root;
|
||||
}
|
||||
|
||||
/* Destroy tree after use */
|
||||
|
||||
void destroy (Node * root) {
|
||||
if (root->lt)
|
||||
destroy(root->lt);
|
||||
if (root->gt)
|
||||
destroy(root->gt);
|
||||
free(root);
|
||||
}
|
||||
|
||||
bool destroyTree (Node **root) {
|
||||
if (!*root)
|
||||
return false;
|
||||
destroy(*root);
|
||||
*root = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main () {
|
||||
int key;
|
||||
Node *root;
|
||||
|
||||
printf("This program allows for the creation of a Binary Search Tree "
|
||||
"(BST) and then finds the node with the smallest key that is greater than "
|
||||
"a given number.\nType in a sequence of integers separated by space to be "
|
||||
"added as keys in the BST and press ENTER to confirm:\n");
|
||||
root = read();
|
||||
|
||||
printf("\nType in an integer to search for a key: ");
|
||||
if (!scanf("%d", &key)) {
|
||||
printf("Invalid input\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\nNext smallest key: %d\n", nextKey(root, key)->key);
|
||||
destroyTree(&root);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#define array int*
|
||||
|
||||
array readArray (int *size, int *max) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*max = 0;
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
if (d > *max)
|
||||
*max = d;
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
array cumulativeFrequency(array A, int size, int max) {
|
||||
int i;
|
||||
array frequency = calloc((max + 1), sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
frequency[A[i] + 1]++;
|
||||
for (i = 1; i <= max; i++)
|
||||
frequency[i] += frequency[i - 1];
|
||||
return frequency;
|
||||
}
|
||||
|
||||
void countingSort (array* A, int size, int max) {
|
||||
int i;
|
||||
array count = cumulativeFrequency(*A, size, max);
|
||||
array sorted = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
sorted[count[(*A)[i]]] = (*A)[i];
|
||||
count[(*A)[i]]++;
|
||||
}
|
||||
free(*A);
|
||||
free(count);
|
||||
*A = sorted;
|
||||
}
|
||||
|
||||
int main () {
|
||||
int i, size, max;
|
||||
array A;
|
||||
|
||||
printf("Este programa admite uma lista de valores inteiros x tais que %d ≤ x ≤ %d e os ordena em ordem crescente.\nDigite uma série de valores inteiros separadas entre si por espaço e pressione ENTER:\n", 0, INT_MAX);
|
||||
A = readArray(&size, &max);
|
||||
|
||||
countingSort(&A, size, max);
|
||||
|
||||
printf("Arranjo ordenado:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
free(A);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#define array int*
|
||||
|
||||
array readArray (int *size, int *max) {
|
||||
int d, i = 0;
|
||||
char c;
|
||||
array A;
|
||||
|
||||
*max = 0;
|
||||
*size = 1;
|
||||
A = malloc(sizeof(int));
|
||||
do {
|
||||
if (!scanf(" %d", &d))
|
||||
continue;
|
||||
if (i == *size - 1) {
|
||||
*size *= 2;
|
||||
A = realloc(A, *size * sizeof(int));
|
||||
}
|
||||
if (d > *max)
|
||||
*max = d;
|
||||
A[i++] = d;
|
||||
} while ((c = getchar()) != EOF && c != '\n');
|
||||
*size = i;
|
||||
return A;
|
||||
}
|
||||
|
||||
array cumulativeFrequency(array A, int size, int exp) {
|
||||
int i, radix;
|
||||
array frequency = calloc(11, sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
radix = A[i] / exp % 10;
|
||||
frequency[radix + 1]++;
|
||||
}
|
||||
for (i = 1; i <= 10; i++)
|
||||
frequency[i] += frequency[i - 1];
|
||||
return frequency;
|
||||
}
|
||||
|
||||
void countingSort (array *A, int size, int exp) {
|
||||
int i, radix;
|
||||
array count = cumulativeFrequency(*A, size, exp);
|
||||
array sorted = malloc(size * sizeof(int));
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
radix = (*A)[i] / exp % 10;
|
||||
sorted[count[radix]] = (*A)[i];
|
||||
count[radix]++;
|
||||
}
|
||||
free(*A);
|
||||
free(count);
|
||||
*A = sorted;
|
||||
}
|
||||
|
||||
void radixSort(array *A, int size, int max) {
|
||||
int exp;
|
||||
|
||||
for (exp = 1; max / exp > 0; exp *= 10)
|
||||
countingSort(A, size, exp);
|
||||
}
|
||||
|
||||
int main () {
|
||||
int i, size, max;
|
||||
array A;
|
||||
|
||||
printf("Este programa admite uma lista de valores inteiros x tais que %d ≤ x ≤ %d e os ordena em ordem crescente.\nDigite uma série de valores inteiros separadas entre si por espaço e pressione ENTER:\n", 0, INT_MAX);
|
||||
A = readArray(&size, &max);
|
||||
|
||||
radixSort(&A, size, max);
|
||||
|
||||
printf("Arranjo ordenado:\n");
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%d ", A[i]);
|
||||
printf("\n");
|
||||
free(A);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
# Bytes, números e caracteres
|
||||
|
||||
## Exercícios 1
|
||||
|
||||
**1.** Mostre que todo número natural pode ser escrito em notação binária.
|
||||
|
||||
Por notação binária admitimos números compostos unicamente por dígitos 0 e 1, tal que o dígito 1 representa a ocorrência de uma distinta potência de 2 (a base, também denominada "base 2") em um somatório. Por exemplo:
|
||||
|
||||
$$
|
||||
0101_2 \equiv 0 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = 5_{10}
|
||||
$$
|
||||
|
||||
Provemos por indução forte que para cada $n \in \mathbb N$ é possível sua representação em forma binária.
|
||||
|
||||
1. Base de indução
|
||||
|
||||
$0_2 = 0 \times 2^0 \equiv 0$ e $1 = 1 \times 2^0 \equiv 1_{10}$.
|
||||
|
||||
2. Hipótese de indução
|
||||
|
||||
Sejam $n, m \in \mathbb N$, $0 \le m < n$ números naturais que, tais quais aqueles em nossa base de indução, podem ser representados por números binários. Se $n$ pode ser representado enquanto número binário, $n + 1$ também deve poder.
|
||||
|
||||
3. Passo de indução
|
||||
|
||||
O número $n + 1$ pode ser par ou ímpar e, portanto, pode ser representado enquanto $2m$ ou $2m + 1$. Sabemos que $m$ é um número da forma $1 \times 2^k + \dots + 1 \times 2^0$ ou $1 \times 2^k + \dots + 0 \times 2^0$, $k \in \mathbb N$. Logo,
|
||||
|
||||
- se $n = 2m$: $n = 1 \times 2^{k + 1} + \dots + 1 \times 2^1 + 0 \times 2^0$, ou $n = 1 \times 2^{k + 1} + \dots + 0 \times 2^1 + 0 \times 2^0$, um número passível de representação binária. $\square$
|
||||
|
||||
- se $n = 2m + 1$: $n = 1 \times 2^{k + 1} + \dots + 1 \times 2^1 + 1 \times 2^0$, ou $n = 1 \times 2^{k + 1} + \dots + 0 \times 2^1 + 1 \times 2^0$, outro número passível de representação binária. $\blacksquare$
|
||||
|
||||
**2.** Mostre que $2^k + 2^{k − 1} + \dots + 2^1 + 2^0 = 2^{k + 1} −1$, qualquer que seja o número natural $k$.
|
||||
|
||||
1. Base de indução
|
||||
|
||||
Seja $k = 0$, então:
|
||||
|
||||
$\displaystyle \sum^k_{i = 0} 2^i = \sum^0_{i = 0} 2^i = 2^0 = 1 = 2^1 - 1$
|
||||
|
||||
2. Hipótese de indução:
|
||||
|
||||
Se $\displaystyle \sum^k_{i = 0} 2^i = 2^{k + 1} - 1$ para todo $k \in \mathbb N$, então também $\displaystyle \sum^{k + 1}_{i = 0} 2^i = 2^{k + 2} - 1$.
|
||||
|
||||
3. Passo de indução:
|
||||
|
||||
$\displaystyle \sum^{k + 1}_{i = 0} 2^i = \sum^k_{i = 0} 2^i + 2^{k + 1} = 2^{k + 1} - 1 + 2^{k + 1} = 2 \cdot 2^{k + 1} - 1 = 2^{k + 2} - 1\ \blacksquare$
|
||||
|
||||
**3.** Escreva os números $2^8$, $2^8 −1$, $2^{16}$, $2^{16} − 1$, $2^{32}$ e $2^{32} − 1$ em notação hexadecimal.
|
||||
|
||||
São os dígitos da base hexadecimal: 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
|
||||
- $2^8_{10} \equiv 10_{16}$
|
||||
- $(2^8 - 1) \equiv \text F_{16}$
|
||||
- $2^{16}_{10} \equiv 100_{16}$
|
||||
- $(2^{16} - 1)_{10} \equiv \text{FF}_{16}$
|
||||
- $2^{32}_{10} \equiv 1000_{16}$
|
||||
- $(2^{32} - 1)_{10} \equiv \text{FFF}_{16}$
|
||||
|
||||
## Exercícios 2
|
||||
|
||||
**1.** Complemento de $n$. Mostramos acima como a notação complemento-de-dois transforma em um inteiro negativo qualquer sequência de $s$ bytes que começa com um bit 1. Agora considere a operação inversa. Dado um inteiro n no intervalo $−2^{8s−1} \dots −1$, mostre que a sequência de $s$ bytes que representa $n$ em notação complemento-de-dois é a mesma sequência de bytes que representa $n + 2^{8s}$ em notação binária.
|
||||
|
||||
Seja $n$ um número inteiro negativo equivalente à $-m$. O número $m$ em notação binária de complemento-de-dois tem seu negativo com representação equivalente àquela de $m - 2^{8s}$. Logo, tem-se que:
|
||||
|
||||
$$
|
||||
m_2 \equiv (m - 2^{8s}) \stackrel{\times -1}{\implies}
|
||||
(-m)_2 \equiv (-m + 2^{8s}) \stackrel{n\ =\ -m}{\implies}
|
||||
n_2 \equiv (n + 2^{8s})_2\ \blacksquare
|
||||
$$
|
||||
|
||||
**2.** Complemento-de-dois. A notação complemento-de-dois transforma qualquer sequência de $s$ bytes que começa com um bit 1 em um inteiro negativo. Agora considere a operação inversa. Suponha que $n$ é um inteiro no intervalo $−2^{8s−1} \dots −1$. Tome a sequência de bits que representa o valor absoluto de $n$ em notação binária, complemente todos os bits (ou seja, toque 0 por 1 e 1 por 0), e some 1, em binário, ao resultado. Mostre que essa operação produz a sequência de $s$ bits que representa n em notação complemento-de-dois.
|
|
@ -0,0 +1,19 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "headers.h"
|
||||
|
||||
int main () {
|
||||
char * bin = NULL;
|
||||
|
||||
printf("Este programa lê um número natural em notação binária e o converte em notação hexadecimal. Digite uma série de uns e zeros, separados ou não entre si por espaços, e pressione ENTER para realizar a conversão:\n");
|
||||
|
||||
switch (readBin(&bin)) {
|
||||
case EOF:
|
||||
printf("Valor inválido detectado\n");
|
||||
case 0:
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\nNotação hexadecimal: 0x%s\n", toHex(bin));
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct node {
|
||||
int digit;
|
||||
struct node *next;
|
||||
} Node;
|
||||
|
||||
Node *binary(Node *stack, int dec) {
|
||||
Node *n = malloc(sizeof(Node));
|
||||
|
||||
n->digit = dec % 2;
|
||||
n->next = stack;
|
||||
return (dec == 0) ? n : binary(n, dec / 2);
|
||||
}
|
||||
|
||||
bool twoComplement(Node *stack) {
|
||||
if (!stack)
|
||||
return false;
|
||||
stack->digit = (stack->digit == 0) ? 1 : 0;
|
||||
|
||||
/* "false" indicates the recursive binary sum hasn't completed */
|
||||
if (!twoComplement(stack->next)) {
|
||||
if (stack->digit == 1) {
|
||||
stack->digit = 0;
|
||||
return false;
|
||||
}
|
||||
stack->digit = 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Node *base2(int dec) {
|
||||
Node *stack = binary(NULL, abs(dec));
|
||||
if (dec < 0)
|
||||
twoComplement(stack);
|
||||
return stack;
|
||||
}
|
||||
|
||||
void printStack(Node *stack) {
|
||||
if (!stack)
|
||||
printf("\n");
|
||||
else {
|
||||
printf("%d", stack->digit);
|
||||
printStack(stack->next);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int dec;
|
||||
|
||||
printf("This program reads an integer number and converts it to its "
|
||||
"equivalent binary number using the two's complement model.\nType "
|
||||
"in a number: ");
|
||||
|
||||
if (!scanf("%d", &dec)) {
|
||||
printf("Invalid input.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Binary equivalent: ");
|
||||
printStack(base2(dec));
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue