Архив за 17.12.2012

Дан массив целочисленных матриц. Вывести матрицы, имеющие наибольшее число нулевых строк.

Решение на C:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
    int a_count;
    printf("Количество матриц: ");
    scanf("%d", &a_count);
 
    int m_count;
    printf("Размер матриц: ");
    scanf("%d", &m_count);
 
    // выделим память для массивов
    int *zeros = malloc(a_count * sizeof(int)),
        **array = malloc(a_count * sizeof(int));
 
    memset(zeros, 0, a_count * sizeof(int));
    // выделим память для каждого элемента массива
    int i;
    for (i = 0; i < a_count; i++) {
        array[i] = malloc(m_count * sizeof(int));
    }
 
    int j, zer_max = 0;
    for (i = 0; i < a_count; i++) {
        printf("Введите элементы %d матрицы: ", i+1);
 
        for (j = 0; j < m_count; j++) {
            scanf("%d", &array[i][j]);
 
            if (array[i][j] == 0) {
                zeros[i]++;
            }
        }
 
        if (zeros[i] > zer_max) {
            zer_max = zeros[i];
        }
    }
 
    if (zer_max == 0) {
        printf("Нет ни одной матрицы с нулём");
        return 0;
    }
 
    printf("Матрицы с максимальным количеством нулей:\n");
    for (i = 0; i < a_count; i++) {
        if (zeros[i] == zer_max) {
            for (j = 0; j < m_count; j++) {
                printf("%d ", array[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

Решение на Pascal:

var
    i, j, zer_max, a_count, m_count: integer;
    {так как нет динамических массивов, примем максимальное значение за 1000}
    zeros: array [0..1000] of integer;
    arr: array [0..1000, 0..1000] of integer;
 
begin
    write('Количество матриц: ');
    readln(a_count);
 
    write('Размер матриц: ');
    readln(m_count);
 
    zer_max := 0;
    for i := 0 to 1000 do
        zeros[i] := 0;
 
    for i := 0 to a_count-1 do begin
        write('Введите элементы ', i+1, ' матрицы: ');
 
        for j := 0 to m_count-1 do begin
            readln(arr[i][j]);
 
            if (arr[i][j] = 0) then
                zeros[i] := zeros[i] + 1;
 
        end;
 
        if (zeros[i] > zer_max) then
            zer_max := zeros[i];
 
    end;
 
    if (zer_max = 0) then begin
        writeln('Нет ни одной матрицы с нулём');
        exit;
    end;
 
    writeln('Матрицы с максимальным количеством нулей:');
    for i := 0 to a_count-1 do begin
        if (zeros[i] = zer_max) then begin
            for j := 0 to m_count-1 do
                writeln(arr[i][j], ' ');
 
            writeln('');
        end;
    end;
 
end.

uInfo v1.1.0

Написал первую версию своего класса для определения данных пользователя по данным $_SERVER[‘HTTP_USER_AGENT’]. Сейчас готова лишь первая тестовая версия, которая не может определять так много данных, как предыдущая. В будущем будет улучшаться. Также проект переехал на GitHub.

Проект Open-Source, написан на PHP, лежит на GitHub
Живой пример работы: http://ip.ziggi.org/
GIT: https://github.com/ziggi/uInfo.git

Быстрый негатив bmp изображения в C++

Написал куда более быстрый вариант инверсии bmp изображения на C++, чем предыдущий. В этом варианте мы читаем изображение, записывая всю информацию о нём в массив, и создаём новое изображение с такими-же данными заголовков, но с инверсированными данными цветов. Всё работает значительно быстрее и код стал более простым.

Файл main.h

#ifndef MAIN_H_INCLUDED
#define MAIN_H_INCLUDED
 
 
typedef struct
{
    unsigned int    bfType;
    unsigned long   bfSize;
    unsigned int    bfReserved1;
    unsigned int    bfReserved2;
    unsigned long   bfOffBits;
} BITMAPFILEHEADER;
 
typedef struct
{
    unsigned int    biSize;
    int             biWidth;
    int             biHeight;
    unsigned short  biPlanes;
    unsigned short  biBitCount;
    unsigned int    biCompression;
    unsigned int    biSizeImage;
    int             biXPelsPerMeter;
    int             biYPelsPerMeter;
    unsigned int    biClrUsed;
    unsigned int    biClrImportant;
} BITMAPINFOHEADER;
 
typedef struct
{
    int   rgbBlue;
    int   rgbGreen;
    int   rgbRed;
    int   rgbReserved;
} RGBQUAD;
 
 
static unsigned short read_u16(FILE *fp);
static unsigned int   read_u32(FILE *fp);
static int            read_s32(FILE *fp);
 
static void write_u16(unsigned short input, FILE *fp);
static void write_u32(unsigned int input, FILE *fp);
static void write_s32(int input, FILE *fp);
#endif // MAIN_H_INCLUDEDs

Файл main.cpp

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "main.h"
 
int main()
{
    printf("Starting...\n");
    FILE *pFile = fopen("input.bmp", "rb");
 
    // считываем заголовок файла
    BITMAPFILEHEADER header;
 
    header.bfType      = read_u16(pFile);
    header.bfSize      = read_u32(pFile);
    header.bfReserved1 = read_u16(pFile);
    header.bfReserved2 = read_u16(pFile);
    header.bfOffBits   = read_u32(pFile);
 
    // считываем заголовок изображения
    BITMAPINFOHEADER bmiHeader;
 
    bmiHeader.biSize          = read_u32(pFile);
    bmiHeader.biWidth         = read_s32(pFile);
    bmiHeader.biHeight        = read_s32(pFile);
    bmiHeader.biPlanes        = read_u16(pFile);
    bmiHeader.biBitCount      = read_u16(pFile);
    bmiHeader.biCompression   = read_u32(pFile);
    bmiHeader.biSizeImage     = read_u32(pFile);
    bmiHeader.biXPelsPerMeter = read_s32(pFile);
    bmiHeader.biYPelsPerMeter = read_s32(pFile);
    bmiHeader.biClrUsed       = read_u32(pFile);
    bmiHeader.biClrImportant  = read_u32(pFile);
 
 
    // инициализация массива пикселей
    RGBQUAD *pixels = new RGBQUAD[bmiHeader.biHeight * bmiHeader.biWidth];
 
    // читаем байты цветов
    for (int i = 0; i < bmiHeader.biHeight * bmiHeader.biWidth; i++) {
        pixels[i].rgbBlue = getc(pFile);
        pixels[i].rgbGreen = getc(pFile);
        pixels[i].rgbRed = getc(pFile);
    }
    fclose(pFile);
 
 
    FILE *oFile = fopen("output.bmp", "wb");
 
    // записываем заголовок файла
    write_u16(header.bfType, oFile);
    write_u32(header.bfSize, oFile);
    write_u16(header.bfReserved1, oFile);
    write_u16(header.bfReserved2, oFile);
    write_u32(header.bfOffBits, oFile);
 
    // записываем заголовок изображения
    write_u32(bmiHeader.biSize, oFile);
    write_s32(bmiHeader.biWidth, oFile);
    write_s32(bmiHeader.biHeight, oFile);
    write_u16(bmiHeader.biPlanes, oFile);
    write_u16(bmiHeader.biBitCount, oFile);
    write_u32(bmiHeader.biCompression, oFile);
    write_u32(bmiHeader.biSizeImage, oFile);
    write_s32(bmiHeader.biXPelsPerMeter, oFile);
    write_s32(bmiHeader.biYPelsPerMeter, oFile);
    write_u32(bmiHeader.biClrUsed, oFile);
    write_u32(bmiHeader.biClrImportant, oFile);
 
    // записываем байты цветов
    for (int i = 0; i < bmiHeader.biHeight * bmiHeader.biWidth; i++) {
        putc(~pixels[i].rgbBlue & 0xFF, oFile);
        putc(~pixels[i].rgbGreen & 0xFF, oFile);
        putc(~pixels[i].rgbRed & 0xFF, oFile);
    }
 
    fclose(oFile);
    printf("Complete\n");
    return 0;
}
 
 
static unsigned short read_u16(FILE *fp)
{
    unsigned char b0, b1;
 
    b0 = getc(fp);
    b1 = getc(fp);
 
    return ((b1 << 8) | b0);
}
 
 
static unsigned int read_u32(FILE *fp)
{
    unsigned char b0, b1, b2, b3;
 
    b0 = getc(fp);
    b1 = getc(fp);
    b2 = getc(fp);
    b3 = getc(fp);
 
    return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}
 
 
static int read_s32(FILE *fp)
{
    unsigned char b0, b1, b2, b3;
 
    b0 = getc(fp);
    b1 = getc(fp);
    b2 = getc(fp);
    b3 = getc(fp);
 
    return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}
 
static void write_u16(unsigned short input, FILE *fp)
{
    putc(input, fp);
    putc(input >> 8, fp);
}
 
static void write_u32(unsigned int input, FILE *fp)
{
    putc(input, fp);
    putc(input >> 8, fp);
    putc(input >> 16, fp);
    putc(input >> 24, fp);
}
 
static void write_s32(int input, FILE *fp)
{
    putc(input, fp);
    putc(input >> 8, fp);
    putc(input >> 16, fp);
    putc(input >> 24, fp);
}

Негатив bmp изображения на C++

UPDATED: Здесь гораздо более быстрый и правильный вариант программы!

Задача: сделать негатив(инверсию) bmp изображения.
Логика решения этой задачи очень похожа на предыдущую, но теперь мы не записываем пиксели в массив, а сразу их инверсируем и записываем в файл. Для этого используем свою функцию inv_byte.

static void inv_byte(FILE *fp)
{
    fseek(fp, ftell(fp), SEEK_SET); // фикс для windows, на linux не обязателен
    int byte = getc(fp);
    fseek(fp, -1, SEEK_CUR);
    putc(~byte & 0xFF, fp);
}

В этой функции мы сначала считываем байт, записывая его: int byte = getc(fp);
Далее смещаем указатель на один байт влево, так как функция getc его переместила
И записываем старший разряд инверсированного байта на место старого байта.
И так для каждого пиксела.

Стоит отметить что printf(«%.2f%%\n\033[0F», progress / pixels * 100) не будет правильно работать в консоли Windows. Поэтому для Windows нужно использовать следующий код:

system("cls");
printf("%.2f%%\n", progress / pixels * 100);

Файл main.h

#ifndef MAIN_H_INCLUDED
#define MAIN_H_INCLUDED
 
 
typedef struct
{
    unsigned int    bfType;
    unsigned long   bfSize;
    unsigned int    bfReserved1;
    unsigned int    bfReserved2;
    unsigned long   bfOffBits;
} BITMAPFILEHEADER;
 
typedef struct
{
    unsigned int    biSize;
    int             biWidth;
    int             biHeight;
    unsigned short  biPlanes;
    unsigned short  biBitCount;
    unsigned int    biCompression;
    unsigned int    biSizeImage;
    int             biXPelsPerMeter;
    int             biYPelsPerMeter;
    unsigned int    biClrUsed;
    unsigned int    biClrImportant;
} BITMAPINFOHEADER;
 
 
static unsigned short read_u16(FILE *fp);
static unsigned int   read_u32(FILE *fp);
static int            read_s32(FILE *fp);
static void inv_byte(FILE *fp);
 
#endif // MAIN_H_INCLUDEDs

Файл main.cpp

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "main.h"
 
int main()
{
    FILE *pFile = fopen("file.bmp", "r+b");
 
    // считываем заголовок файла
    BITMAPFILEHEADER header __attribute__((unused));
 
    header.bfType      = read_u16(pFile);
    header.bfSize      = read_u32(pFile);
    header.bfReserved1 = read_u16(pFile);
    header.bfReserved2 = read_u16(pFile);
    header.bfOffBits   = read_u32(pFile);
 
    // считываем заголовок изображения
    BITMAPINFOHEADER bmiHeader;
 
    bmiHeader.biSize          = read_u32(pFile);
    bmiHeader.biWidth         = read_s32(pFile);
    bmiHeader.biHeight        = read_s32(pFile);
    bmiHeader.biPlanes        = read_u16(pFile);
    bmiHeader.biBitCount      = read_u16(pFile);
    bmiHeader.biCompression   = read_u32(pFile);
    bmiHeader.biSizeImage     = read_u32(pFile);
    bmiHeader.biXPelsPerMeter = read_s32(pFile);
    bmiHeader.biYPelsPerMeter = read_s32(pFile);
    bmiHeader.biClrUsed       = read_u32(pFile);
    bmiHeader.biClrImportant  = read_u32(pFile);
 
    float pixels = bmiHeader.biWidth * bmiHeader.biHeight;
    float progress = 0;
    for (int i = 0; i < bmiHeader.biWidth; i++) {
        for (int j = 0; j < bmiHeader.biHeight; j++) {
            inv_byte(pFile);
            inv_byte(pFile);
            inv_byte(pFile);
            progress++;
        }
        // выводим процент готовности
        printf("%.2f%%\n\033[0F", progress / pixels * 100);
        // пропускаем последний байт в строке
        getc(pFile);
    }
    fclose(pFile);
    return 0;
}
 
static void inv_byte(FILE *fp)
{
    fseek(fp, ftell(fp), SEEK_SET); // фикс для windows, на linux не обязателен
    int byte = getc(fp);
    fseek(fp, -1, SEEK_CUR);
    putc(~byte & 0xFF, fp);
}
 
static unsigned short read_u16(FILE *fp)
{
    unsigned char b0, b1;
 
    b0 = getc(fp);
    b1 = getc(fp);
 
    return ((b1 << 8) | b0);
}
 
 
static unsigned int read_u32(FILE *fp)
{
    unsigned char b0, b1, b2, b3;
 
    b0 = getc(fp);
    b1 = getc(fp);
    b2 = getc(fp);
    b3 = getc(fp);
 
    return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}
 
 
static int read_s32(FILE *fp)
{
    unsigned char b0, b1, b2, b3;
 
    b0 = getc(fp);
    b1 = getc(fp);
    b2 = getc(fp);
    b3 = getc(fp);
 
    return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}

Чтение bmp в C++

UPDATED: Здесь более правильный вариант программы!

Задача: из bmp изображения записать в двумерный массив информацию о цвете каждого пикселя, с использованием только стандартных библиотек.

Решение этой задачи покажется очень простым, если знать спецификацию bmp формата. Байты с цветами каждого пиксела начинаются с 54-го байта и при считывании заголовков bmp формата, указатель сместился на нужную нам позицию. Считать байт можно функцией getc(FILE *stream). Цвета каждого пиксела находятся в формате BGR(не привычный нам RGB). Остается прочитать по порядку каждый байт и записать все значения в двумерный массив.

Файл main.h

#ifndef MAIN_H_INCLUDED
#define MAIN_H_INCLUDED
 
 
typedef struct
{
    unsigned int    bfType;
    unsigned long   bfSize;
    unsigned int    bfReserved1;
    unsigned int    bfReserved2;
    unsigned long   bfOffBits;
} BITMAPFILEHEADER;
 
typedef struct
{
    unsigned int    biSize;
    int             biWidth;
    int             biHeight;
    unsigned short  biPlanes;
    unsigned short  biBitCount;
    unsigned int    biCompression;
    unsigned int    biSizeImage;
    int             biXPelsPerMeter;
    int             biYPelsPerMeter;
    unsigned int    biClrUsed;
    unsigned int    biClrImportant;
} BITMAPINFOHEADER;
 
typedef struct
{
    int   rgbBlue;
    int   rgbGreen;
    int   rgbRed;
    int   rgbReserved;
} RGBQUAD;
 
 
static unsigned short read_u16(FILE *fp);
static unsigned int   read_u32(FILE *fp);
static int            read_s32(FILE *fp);
 
#endif // MAIN_H_INCLUDEDs

Файл main.cpp

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "main.h"
 
int main()
{
    FILE * pFile = fopen("file.bmp", "rb");
 
    // считываем заголовок файла
    BITMAPFILEHEADER header __attribute__((unused));
 
    header.bfType      = read_u16(pFile);
    header.bfSize      = read_u32(pFile);
    header.bfReserved1 = read_u16(pFile);
    header.bfReserved2 = read_u16(pFile);
    header.bfOffBits   = read_u32(pFile);
 
    // считываем заголовок изображения
    BITMAPINFOHEADER bmiHeader;
 
    bmiHeader.biSize          = read_u32(pFile);
    bmiHeader.biWidth         = read_s32(pFile);
    bmiHeader.biHeight        = read_s32(pFile);
    bmiHeader.biPlanes        = read_u16(pFile);
    bmiHeader.biBitCount      = read_u16(pFile);
    bmiHeader.biCompression   = read_u32(pFile);
    bmiHeader.biSizeImage     = read_u32(pFile);
    bmiHeader.biXPelsPerMeter = read_s32(pFile);
    bmiHeader.biYPelsPerMeter = read_s32(pFile);
    bmiHeader.biClrUsed       = read_u32(pFile);
    bmiHeader.biClrImportant  = read_u32(pFile);
 
 
    RGBQUAD **rgb = new RGBQUAD*[bmiHeader.biWidth];
    for (int i = 0; i < bmiHeader.biWidth; i++) {
        rgb[i] = new RGBQUAD[bmiHeader.biHeight];
    }
 
    for (int i = 0; i < bmiHeader.biWidth; i++) {
        for (int j = 0; j < bmiHeader.biHeight; j++) {
            rgb[i][j].rgbBlue = getc(pFile);
            rgb[i][j].rgbGreen = getc(pFile);
            rgb[i][j].rgbRed = getc(pFile);
        }
 
        // пропускаем последний байт в строке
        getc(pFile);
    }
 
    // выводим результат
    for (int i = 0; i < bmiHeader.biWidth; i++) {
        for (int j = 0; j < bmiHeader.biHeight; j++) {
            printf("%d %d %d\n", rgb[i][j].rgbRed, rgb[i][j].rgbGreen, rgb[i][j].rgbBlue);
        }
        printf("\n");
    }
 
    fclose(pFile);
    return 0;
}
 
 
static unsigned short read_u16(FILE *fp)
{
    unsigned char b0, b1;
 
    b0 = getc(fp);
    b1 = getc(fp);
 
    return ((b1 << 8) | b0);
}
 
 
static unsigned int read_u32(FILE *fp)
{
    unsigned char b0, b1, b2, b3;
 
    b0 = getc(fp);
    b1 = getc(fp);
    b2 = getc(fp);
    b3 = getc(fp);
 
    return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}
 
 
static int read_s32(FILE *fp)
{
    unsigned char b0, b1, b2, b3;
 
    b0 = getc(fp);
    b1 = getc(fp);
    b2 = getc(fp);
    b3 = getc(fp);
 
    return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0);
}

Сортировка массива с условием

Если в целочисленной последовательности нет других чисел кроме x, y, z, то упорядочить последовательность по убыванию(невозрастанию).

Решение на C:

#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    int count;
    printf("Количество элементов в последовательности: ");
    scanf("%d", &count);
 
    int i, *input = malloc(count * sizeof(int)),
        x = -1, y = -1, z = -1;
 
    for (i = 0; i < count; i++) {
        printf("Введи %d элемент: ", i);
        scanf("%d", &input[i]);
 
        // свободны ли места для новых чисел
        if (x == -1) {
            x = input[i];
        } else if (y == -1) {
            y = input[i];
        } else if (z == -1) {
            z = input[i];
        }
 
        // если мест для новых чисел нет
        if (input[i] != x && input[i] != y && input[i] != z) {
            printf("В последовательности есть другие числа, кроме x, y, z");
            return 0;
        }
    }
 
    // сортируем
    int j;
    for (i = 0; i < count; i++) {
        for (j = 0; j < count - 1; j++) {
            if (input[j] < input[j+1]) {
                int tmp = input[j];
                input[j] = input[j+1];
                input[j+1] = tmp;
            }
        }
    }
 
    // выводим
    for (i = 0; i < count; i++) {
        printf("%d ", input[i]);
    }
    return 0;
}

Решение на Pascal:

var
    i, j, tmp, count, x, y, z: longint;
    {так как нет динамических массивов, примем максимальное значение за 1000}
    input: array [0..1000] of longint;
begin
    write('Количество элементов в последовательности: ');
    readln(count);
 
    x := -1;
    y := -1;
    z := -1;
 
    for i := 0 to count-1 do begin
        write('Введи ',i,' элемент: ');
        readln(input[i]);
 
        {свободны ли места для новых чисел}
        if (x = -1) then
            x := input[i]
        else if (y = -1) then
            y := input[i]
        else if (z = -1) then
            z := input[i];
 
        {если мест для новых чисел нет}
        if ((input[i] <> x) and (input[i] <> y) and (input[i] <> z)) then begin
            writeln('В последовательности есть другие числа, кроме x, y, z');
            exit;
        end;
    end;
 
    {сортируем}
    for i := 0 to count-1 do begin
        for j := 0 to count-2 do begin
            if (input[j] < input[j+1]) then begin
                tmp := input[j];
                input[j] := input[j+1];
                input[j+1] := tmp;
            end;
        end;
    end;
 
    // выводим
    for i := 0 to count-1 do
        write(input[i], ' ');
end.

Нахождение суммы цифр числа

Дано целое число n, удовлетворяющее условию 0 < |n| <= 2*10^9. Найти сумму цифр числа n.

Решение на C:

#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    printf("Введите число: ");
    int n;
    scanf("%d", &n);
 
    int sum = 0;
    n = abs(n);
    while (n != 0) {
        sum += n % 10;
        n /= 10;
    }
 
    printf("sum = %d", sum);
    return 0;
}

Решение на Pascal:

var
    sum, n: longint;
begin
    write('Введите число: ');
    readln(n);
 
    sum := 0;
    n := abs(n);
    while n <> 0 do begin
        sum := sum + n mod 10;
        n := n div 10;
    end;
 
    writeln('sum = ', sum);
end.
Перейти к верхней панели