Страницы

Translate

воскресенье, 18 августа 2013 г.

Exercise 4-1. Write the function strindex(s,t) which returns the position of the rightmost occurrence of t in s, or -1 if there is none.

Exercise 4-1. Write the function strindex(s,t) which returns the position of the rightmost
occurrence of t in s, or -1 if there is none.

#include <stdio.h>

#define MAXLINE 1000 /*maximum input line lenght*/
#define MAXPATTERN 20

int getlin(char line[], int max);
int strindex(char source[], char searchfor[]);

char pattern[MAXPATTERN]; /*pattern to search for*/

/*find all line matching pattern*/
int main()
{
    char line[MAXLINE];
    int found, i;
    found = 0;
    
    printf("Enter the pattern: ");
    gets(pattern);
    while(getlin(line, MAXLINE) > 0)
        if((i = strindex(line, pattern)) >=0)
        {
            printf("%s", line);
            printf("the position of the rightmost occurence: %d\n", i);
            found++;
        }
        else 
            printf("occurence: %d\n", i);
    printf("%d\n", found);
    return 0;
}


/*getlin: get line into line[], return lenght*/
int getlin(char line[], int max)
{
    int c, i;
    
    i = 0;
    printf("Enter the line: ");
    while(--max > 0 && (c=getchar()) != EOF && c != '\n')
        line[i++] = c;
    if(c == '\n')
        line[i++] = c;
    line[i] = '\0';
    return i;
}

/*strindex: return index of pattern in line, -1 if none*/
int strindex(char source[], char searchfor[])
{
    int i, j, k, pos;
    
    for(pos = -1, i = 0; source[i] != '\0'; i++)
    {
        for(j = i, k = 0; searchfor[k] != '\0' && source[j] == searchfor[k]; j++, k++)
            ;
        if(k > 0 && searchfor[k] == '\0')
            pos = i;
    }
    return pos;
}

Result:


среда, 14 августа 2013 г.

Упражнение 3.6. Напишите версию itoa с дополнительным третьим аргументом, задающим минимальную ширину поля.

Упражнение 3.6. Напишите версию itoa с дополнительным третьим аргументом, задающим минимальную ширину поля. При необходимости преобразованное число должно слева дополняться пробелами.

#include <stdio.h>
#include <string.h>
#define LEN 100


void itoa(int n, char s[], int w);
void reverse(char s[]);
int abs(int x);

int main()
{
    int n, w;
    char s[LEN];
    
    printf("Enter the number: ");
    scanf("%d", &n);
    printf("Enter the field width: ");
    scanf("%d", &w);
    itoa(n, s, w);
    printf("%s", s);
    printf("\n");
    return 0;
}

/*itoa*/
void itoa(int n, char s[], int w)
{
    int i, sign;
    
    sign = n; //сохраняем знак
    i = 0;
    do //генерируем цифры в обратном порядке
    {
        s[i] = abs(n % 10) + '0'; //следующая цифра
        i++;
    } while ((n /= 10) != 0);
    if (sign < 0)
        s[i++] = '-';
    while((i+1) <= w)//дополняем пробелами
        s[i++] = '|';//для наглядности вместо пробелов '|'
    s[i] = '\0';
    reverse(s);
}

/*reverse*/
void reverse(char s[])
{
    int i, j;
    char c;
    
    for(i = 0, j = strlen(s) - 1; i < j; i++, j--)
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

/*abs*/
int abs(int x)
{
    return ((x) < 0? -(x) : (x));
}

Результат:


Упражнение 3.5. Напишите функцию itob(n, s, b), которая переводит целое n в строку s, представляющую число по основанию b.

Упражнение 3.5. Напишите функцию itob(n, s, b), которая переводит целое n в строку s, представляющую число по основанию b. В частности, itob(n, s, 16) помещает в s текст числа n в шестнадцатеричном виде.

#include <stdio.h>
#include <string.h>
#define LEN 100

void itob(int n, char s[], int b);
void reverse(char s[]);
int abs(int x);

int main()
{
    int n, b;
    char s[LEN];
    
    printf("Enter the number n: ");
    scanf("%d", &n);
    printf("base b: ");
    scanf("%d", &b);
    itob(n, s, b);
    printf("%s", s);
    printf("\n");
    return 0;
}

/*itob*/
void itob(int n, char s[], int b)
{
    int i, sign, c;
    
    sign = n; //сохраняем знак
    if(sign < 0)
        n = -n;
    i = 0;
    do //генерируем цифры в обратном порядке
    {
        c = (n % b);
        s[i++] = (c>9) ? c+'A'-10: c + '0';//если 16-ричное отображение
        n /= b;                            //подбираем буквы
    } while (n >= 1);
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

/*reverse*/
void reverse(char s[])
{
    int i, j;
    char c;
    
    for(i = 0, j = strlen(s) - 1; i < j; i++, j--)
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

Результат:




Упражнение 3.4. Модифицируйте программу itoa.

Упражнение 3.4. При условии, что для представления чисел используется дополнительный код, наша версия itoa не справляется с самым большим по модулю отрицательным числом, значение которого равняется -(2n-1), где n — размер слова. Объясните, чем это вызвано. Модифицируйте программу таким образом, чтобы она давала правильное значение указанного числа независимо от машины, на которой выполняется.

#include <stdio.h>
#include <string.h>
#define LEN 100

void itoa(int n, char s[]);
void reverse(char s[]);
int abs(int x);

int main()
{
    int n;
    char s[LEN];
    
    printf("Enter the number: ");
    scanf("%d", &n);
    itoa(n, s);
    printf("%s", s);
    printf("\n");
    return 0;
}

/*itoa*/
void itoa(int n, char s[])
{
    int i, sign;
    
    sign = n; //сохраняем знак
    i = 0;
    do //генерируем цифры в обратном порядке
    {
        s[i] = abs(n % 10) + '0'; //следующая цифра
        i++;
    } while ((n /= 10) != 0);
    if (sign < 0)
        s[i++] = '-';
    s[i] = '\0';
    reverse(s);
}

void reverse(char s[])
{
    int i, j;
    char c;
    
    for(i = 0, j = strlen(s) - 1; i < j; i++, j--)
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

int abs(int x)
{
    return ((x) < 0? -(x) : (x));
}

Результат:




суббота, 10 августа 2013 г.

Упражнение 3.3. Напишите функцию expand(s1, s2), заменяющую сокращенную запись наподобие a-z в строке s1 эквивалентной полной записью abc. . . xyz в s2.

Упражнение 3.3. Напишите функцию expand(s1, s2), заменяющую сокращенную запись наподобие a-z в строке s1 эквивалентной полной записью abc. . . xyz в s2. В s1 допускаются буквы (прописные и строчные) и цифры. Следует уметь справляться с такими случаями, как a-b-c, a-z0-9 и -а-b. Считайте знак - в начале или в конце s1 обычным символом минус.


#include <stdio.h>
#define LEN 500

void expand(char s1[], char s2[]);

int main()
{
    char s1[LEN], s2[LEN];
    int c, i;
    
    for(i = 0; (c = getchar()) != EOF; i++)//заполняем массив знаками
        s1[i] = c;
    s1[i] = '\0';
    expand(s1, s2);
    printf("%s", s2);
    printf("\n");
    return 0;
}

/*expand*/
void expand(char s1[], char s2[])
{
    int i, j;
    char c;

    for(i=j=0; (c=s1[i++]) != '\0';)
    {
        /*если '-'встречается внутри 
         * строки( a-z -a-z) после пробела*/
        if(c == ' ' && s1[i] == '-')
            s2[j++] = c;
        else if(s1[i] =='-' && s1[i+1] >=c)
        {
            i++;
            while(c<s1[i])//печатаем полный список
                s2[j++] = c++;
        }
        else
            s2[j++] = c;
            
    }
    s2[j] = '\0';
}

Результат:


Упражнение 3.2. Напишите функцию escape(s, t), которая при копировании текста из t в s преобразует такие символы, как новая строка и табуляция в "видимые последовательности символов" (вроде \n и \t).

Упражнение 3.2. Напишите функцию escape(s, t), которая при копировании текста из t в s преобразует такие символы, как новая строка и табуляция в "видимые последовательности символов" (вроде \n и \t). Используйте инструкцию switch. Напишите функцию, выполняющую обратное преобразование эскейп- последовательностей в настоящие символы.

#include <stdio.h>
#define LEN 200

void escape(char s[], char t[]);
void reescape(char t2[], char s[]);

int main()
{
    char t[LEN], s[LEN], t2[LEN];
    int c, i;
    
    i = 0;
    while((c=getchar()) != EOF)
    {
        t[i] = c;
        i++;
    }
    t[i] = '\0';
    printf("\n");
    escape(s, t);
    reescape(t2, s);
    printf("%s", s);
    printf("\n\n");
    printf("%s", t2);
    printf("\n");
    return 0;
}

/*escape*/
void escape(char s[], char t[])
{
    int i, j;
    i = j = 0;
    
    while(t[i] != '\0')
    {
        switch (t[i])
        {
            case '\t':
                s[j++] = '\\';
                s[j++] = 't';
                i++;
                break;
            case '\n':
                s[j++] = '\\';
                s[j++] = 'n';
                i++;
                break;
            default:
                s[j++] = t[i++];
                break;
        }
    }
    s[j] = '\0';
}

/*reescape*/
void reescape(char t2[], char s[])
{
    int i, j;
    
    i = j = 0;
    while(s[i] != '\0')
    {
        if(s[i] == '\\')
        {
            switch (s[++i])
            {
                case 'n':
                    t2[j++] = '\n';
                    i++;
                    break;
                case 't':
                    t2[j++] = '\t';
                    i++;
                    break;
                default:
                    t2[j++] = s[i++];
                    break;
            }
        }
        else
            t2[j++] = s[i++];
    }
    t2[j] = '\0';
}

Результат:


вторник, 6 августа 2013 г.

Упражнение 3.1.Напишите программу binsearch(), предусмотрев в ней одну проверку внутри цикла.

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

#include <stdio.h>


int binsearch(int x, int v[], int n);

int main()
{
    int x;
    
    x = 8;
    int v[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    printf("%d\n", binsearch(x, v, 10));
    return 0;
}
    

/*binsearch()*/
int binsearch(int x, int v[], int n)
{
    int low, high, mid;
    
    low = 0;
    high = n - 1;
    mid = (low+high)/2;
    while(low<=high && x != v[mid])
    {
        if(x < v[mid])
            high = mid - 1;
        else if(x > v[mid])
            low = mid + 1;
        mid = (low + high)/2;
    }
    if(x==v[mid])//совпадение найдено
        return mid;
    else
        return -1;//нет совпадений
}

Результат: