Записки программиста Программирование и не только

9Окт/120

[Java] Консольный ввод/вывод

Любимое занятие - написание консольных диалоговых приложений :)

Во время работы метода System.in.read возможно возникновение исключений. Поэтому заключаем фрагмент кода, выполняющий эту функцию, в блок try-catch.

import java.util.StringTokenizer;    //добавляем класс для обработки строк

public class ioTest {
    public static void main(String args[]) {
        byte bKbd[] = new byte[256];		// буфер
        String szStr = "";					// итоговая строка
        StringTokenizer st;					// преобразователь

        System.out.print("Print here: ");
        try
        {
            // Метод read считывает символы с клавиатуры и записывает
			// их в массив байт с именем bKbd. Этот метод возвращает 
			// управление, когда пользователь закончил ввод и нажал 
			// клавишу <Enter>. При этом в переменную iCnt записывается 
			// количество прочитанных символов.
            int iCnt = System.in.read(bKbd);

            // Строка String содержит 16-разрядные символы Unicode.
            // Чтобы преобразовать массив байт в строку Unicode, мы
			// задаем значение старшего байта во втором параметре 
			// конструктора, равное нулю.
            szStr = new String(bKbd, 0, iCnt);

            // Удаление символов возврата каретки и перевода строки
			// выполняется при помощи класса StringTokenizer, предназначенного 
			// для разбора текстовых строк. Создавая объект этого класса,
			// мы передаем конструктору через второй параметр список 
			// символов-разделителей
            st = new StringTokenizer(szStr, "\r\n");

            // Метод nextElement возвращает первый элемент строки до разделителя,
			// то есть в нашем случае всю строку до символов возврата каретки и 
			// перевода строки.
            szStr = new String((String)st.nextElement());
        }
        catch(Exception ex)
        {
            System.out.println(ex.toString());
        }

        //чисто для красоты - разделяем строку на слова
        String v[] = szStr.split(" ");
        for(int j = 0; j < v.length; j++)
        {
            System.out.println(j + "-е слово: " + v[j]);
        }
    }
}

Как пользоваться:
Запускаем, внизу в консоли тыкаем в белое поле и набираем строку. Ввод заканчиваем нажатием клавиши

Как-то вот так:

Print here: Это странная консольная программа!
0-е слово: Это
1-е слово: странная
2-е слово: консольная
3-е слово: программа!

Process finished with exit code 0
Метки записи: , Нет комментариев
8Окт/120

[Java] Методы. Статические и нет. Вызов методов.

Итак, в предыдущей статье я написал пример реализации сортировки. Но написал я её в виде функции.

Теперь разберу как её использовать.

Из теории известно, что методы являются частью классов. Чтобы использовать метод без класса, его надо сделать статическим.

Пример с классом:

class Sort {
    void gnom_sort(int[] mas) {
        int p = 2;
        int i = 1;
        for (; i < mas.length; ) {
            if (mas[i - 1] <= mas[i]) {
                p++;
                i = p;
            } else {
                int a = mas[i];
                mas[i] = mas[i - 1];
                mas[i - 1] = a;
                i--;
                if (i == 0) {
                    p++;
                    i = p;
                }
            }
        }
    }
}

public class Hello {
	public static void main(String args[]) {
	int mas[] = {5, 5, 9, 8, 0, -5, 9, 10};
	Sort s1 = new Sort();
	s1.gnom_sort(mas);
}

Пример со статической функцией:

class Sort {
    static void gnom_sort(int[] mas) {
        int p = 2;
        int i = 1;
        for (; i < mas.length; ) {
            if (mas[i - 1] <= mas[i]) {
                p++;
                i = p;
            } else {
                int a = mas[i];
                mas[i] = mas[i - 1];
                mas[i - 1] = a;
                i--;
                if (i == 0) {
                    p++;
                    i = p;
                }
            }
        }
    }
}

public class Hello {
	public static void main(String args[]) {
	int mas[] = {5, 5, 9, 8, 0, -5, 9, 10};
	Sort.gnom_sort(mas);	//Не нужно создавать объект
}

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

public class Hello {
    static void gnom_sort(int[] mas) {
        int p = 2;
        int i = 1;
        for (; i < mas.length; ) {
            if (mas[i - 1] <= mas[i]) {
                p++;
                i = p;
            } else {
                int a = mas[i];
                mas[i] = mas[i - 1];
                mas[i - 1] = a;
                i--;
                if (i == 0) {
                    p++;
                    i = p;
                }
            }
        }
    }

    public static void main(String args[]) {
        int mas[] = {5, 5, 9, 8, 0, -5, 9, 10};
        gnom_sort(mas);	//Просто вызываем
}
Метки записи: , Нет комментариев
8Окт/120

Гномья сортировка (Gnome sort)

Гномья сортировка основана на технике, используемой обычным голландским садовым гномом (нидерл. tuinkabouter). Это метод, которым садовый гном сортирует линию цветочных горшков. По существу он смотрит на следующий и предыдущий садовые горшки: если они в правильном порядке, он шагает на один горшок вперёд, иначе он меняет их местами и шагает на один горшок назад. Граничные условия: если нет предыдущего горшка, он шагает вперёд; если нет следующего горшка, он закончил.
Дик Грун

Мой вариант реализации:

void gnom_sort(int[] mas) {
	int p = 2;
	int i = 1;
	for (; i < mas.length; ) {
		if (mas[i - 1] <= mas[i]) {
			p++;
			i = p;
		} else {
			int a = mas[i];
			mas[i] = mas[i - 1];
			mas[i - 1] = a;
			i--;
			if (i == 0) {
				p++;
				i = p;
			}
		}
	}
}
15Сен/126

[Java] Сортировка пузырьком

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

Что такое сортировка пузырьком?
Это когда последовательно берется каждый элемент массива и "всплывается" на своё место пока не встретит более "легкий" элемент или конец массива.

Что для этого надо?
Для начала, нужно проходить по всему массиву:

for(int i = 0; i < arr.length; i++)

Ничего сложного, да?
Теперь надо каждый найденный элемент поднимать вверх.

for(int i = 1; i < arr.length; i++)	//внимание на начальный номер
					//связано это с тем, что сравниваем с "предыдущим" пузырьком
					//но индекса "-1" в массиве нет
{
	for(int j = i; j >= 1; j--)
	{
		//меняем элементы местами
		int a = arr[j];
		arr[j] = arr[j-1];
		arr[j-1] = a;
	}
}

Элементы "всплывают". Но чего-то не хватает... Точно, проверки - нужно ли вообще всплывать!

for(int i = 1; i < arr.length; i++)
{
	for(int j = i; (j >= 1) && (arr[j] < arr[j - 1]); j--)
	//ПОКА (arr[j] меньше arr[j-1]) И (в массиве еще есть элементы (j >= 0))
        {
                int a = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] = a;
	}
}

Вот так вот.
Массив для проверки можно создать так:

int arr[] = {4, 7, 2, 9, 0, 1, 9, 12 ,56 ,78};

Но мы жешь программисты!
Так что воспользуемся готовой функцией random!

int arr[] = new inr[10];
for(int i = 0; i < arr.length; i++)
	arr[i] = Math.random();

В качестве домашнего задания попробуйте реализовать сортировку по убыванию.
Ну и на сложное - Гномью сортировку (gnome sort)

15Авг/120

[SQL] Простенький бекап для SQLite

Для бекапа средствами SQL, а не самого SQLite'а можно сделать вот так:

//Подсоединяем файл БД, куда будем делать копию:
ATTACH DATABASE 'C:\file.db' AS fileDB;
//Создаём там таблицу путем копирования содержимого:
CREATE TABLE fileDB.qdn AS select * FROM table_name;
//Отсоединяемся:
DETACH fileDB;
Метки записи: , , Нет комментариев
25Июл/122

[SQL] Задачка соискателю

Тема: SQL дерево.
Задача: дана одна сущность с замыканием ключа сам на себя - найти все листья

Таблица:

CREATE TABLE t1 (id integer NOT NULL PRIMARY KEY UNIQUE, id_p integer)

Решение:

SELECT * FROM t1 AS e1 WHERE NOT EXISTS (SELECT * FROM t1 AS e2 WHERE e1.id = e2.id_p)

Т.е. ищем все элементы которые не являются родителем кому-либо

Метки записи: , 2 Комментарии
19Июл/120

[LJ API] getfriends

Спрашиваем список френдов. Возвращает тех, кого вы добавили в друзья.
Метод LJ.XMLRPC.getfriends
Ему необходимо передать логин, пароль и версию протокола.

Пример:

<?xml version="1.0"?>
<methodCall>
	<methodName>LJ.XMLRPC.getfriends</methodName>
	<params><param><value><struct>
		<member><name>username</name><value><string>test</string></value></member>
		<member><name>password</name><value><string>test</string></value></member>
		<member><name>ver</name><value><int>1</int></value></member>
	</struct></value></param></params>
</methodCall>

Отправляем естественно в одну строку без всяких табуляций и переносов.

В ответ получим defaultpicurl, bgcolor, fgcolor, fullname, username

Метки записи: , , Нет комментариев
5Июн/120

[Qt] Запись файла в SQLite

Собственно, всё просто
Создали в БД таблицу с атрибутом типа BLOB:

CREATE TABLE fileTable (id_file integer NOT NULL PRIMARY KEY AUTOINCREMENT, file BLOB NOT NULL);

Потом:

    QFile file(QApplication::applicationDirPath().append("/file"));
    file.open(QIODevice::ReadOnly);    //открыли файл
    QByteArray ba = file.readAll();    //прочитали из него всё
    QSqlQuery query(QSqlDatabase::database("sql"));    //
    query.prepare("INSERT INTO fileTable (file) VALUES(:val);");    //создали запрос
    query.bindValue ( ":val", ba);
    query.exec();    //запустили
    file.close();    //файл закрыли

И всё. Ну, естественно, дописали обработку ошибок.

Обратный процесс - чтение файла из SQLite:

    QFile file(QApplication::applicationDirPath().append("/newfile"));
    file.open(QIODevice::WriteOnly);
    QSqlQuery query(QSqlDatabase::database("sql"));

    query.prepare("SELECT file FROM fileTable;");
    query.exec();

    query.next();
    QByteArray ba = query.value(0).toByteArray();
    file.write(ba);
    file.close();
Метки записи: , , , Нет комментариев
28Апр/120

qDebug() и структуры

В дополнении к этому

Есть в классе произвольная структура.
Надо научить её выводиться в qDebug()

Структура:

class MyClass
{
    struct MyStruct
    {
        quint8 a1;
        quint8 a2;
        quint8 a3;
        quint8 a4;
    };
};

Дописываем в *.h :

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug, const MyClass::MyStruct);
#endif

А в *.cpp :

QDebug operator<<(QDebug aDbg, const MyClass::MyStruct strc)
{
    aDbg.nospace() << "( " << "MyStruct" << " ("
                   << strc.a1 << ", "
                   << strc.a2 << ", "
                   << strc.a3 << ", "
                   << strc.a4
                   << ") )";
    return aDbg.space();
}
Метки записи: , , Нет комментариев
20Апр/120

[QtScript] Получить доступ из пользовательской функции к интерфейсу.

Продолжаем извращаться.

Захотелось мне написать свою функцию print для QtScript чтобы вывод шел в QTextEdit.
Класс, который содержит в себе TextEdit у меня зовётся Widget

Функция (Вне классов):

QScriptValue funcPrint(QScriptContext *context, QScriptEngine *engine)
{
    QString result;
    for (int i = 0; i < context->argumentCount(); ++i) {
        if (i > 0)
            result.append(" ");
        result.append(context->argument(i).toString());
    }

    Widget *bgg = (Widget*)engine->parent();
    bgg->print(result);

    return engine->undefinedValue();
}

Регистрируем:

engine->globalObject().setProperty("print", engine->newFunction(funcPrint, 1));

Метод банален:

void Widget::print(QString aStr)
{
    ui->TextEdit->append(aStr);
}

Тонкости:
engine является членом класса Widget (приватным) и инициализируется:

engine = new QScriptEngine(this);

Обязательно указать родителя! Иначе его потом не получить и будет segfault

Соответственно можно объявить engine и не указателем.
Тогда обязательно(!) инициализировать в конструкторе:

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),
    engine(this)              //!!!!!
{
    ui->setupUi(this);
    ...
}
Метки записи: , , Нет комментариев