Перенос кода произвольного доступа в PHP - PullRequest
0 голосов
/ 27 декабря 2011
#include <fstream>
#include <iostream>

using namespace std;

bool find_in_file(char*);
void insert_in_file(char*);
inline bool isNull(char* word);

int main()
{
    char word[25];

    for(int i = 0; i < 10; i++)
    {
        cin >> word;

        if( find_in_file(word) )
            cout << "found" << endl;
        else
            insert_in_file(word);
    }
    system("pause");
}

bool find_in_file(char* word)
{
    ifstream file;
    file.open("file.dat", ios::in);
    char contents[655][25] = {0};


    file.read(reinterpret_cast<char*>(contents), 16*1024);
    file.close();

    int i = 0;

    while( !isNull(contents[i]) )
    {
        if( strcmp(contents[i], word) == 0)
            return true;

        if( strcmp(contents[i], word) < 0 )
            i = 2*i + 2;
        else
            i = 2*i + 1;
    }

    return false;
}

void insert_in_file(char* word)
{
    fstream file;
    file.open("file.dat", ios::in | ios::binary);
    char contents[655][25] = {0};

    file.read(reinterpret_cast<char*>(contents), 16*1024);
    file.close();


    file.open("file.dat", ios::in | ios::out | ios::binary);

    if( isNull(contents[0]) )
    {
        file.write(word, 25);
        file.close();
        return;
    }

    int parent;
    int current = 0;

    while( !isNull(contents[current]) )
    {
        parent = current;

        if( strcmp( contents[current], word ) < 0 )
            current = current*2 + 2;
        else if ( strcmp( contents[current], word ) > 0)
            current = current*2 + 1;
        else
            return;
    }

    int insertAt;

    if( strcmp(contents[parent], word ) < 0 )
        insertAt = parent*2 + 2;
    else
        insertAt = parent*2 + 1;

    file.seekp(insertAt*25, ios_base::beg);
    file.write(reinterpret_cast<const char*>(word), 25);
    file.close();
}

inline bool isNull(char* word)
{
    return word[0] == 0;
}

Приведенный выше код реализует двоичное дерево поиска в файле. Он использует массивы символов длиной 25 в качестве узлов. Максимальный размер файла - около 16 КБ. Дерево хранится в следующем формате:

0 root
1 left child of root - L
2 right child of root - R
3 left child of L - LL
4 right child of L - LR
5 left child of R - RL
6 right child of R - RR

и так далее. При отсутствии дочернего элемента вставляется пустой узел. Теперь я должен сделать то же самое в PHP. Как это возможно, поскольку, насколько я знаю, PHP не обеспечивает доступ к двоичным файлам. С нетерпением жду ваших ответов:)

edit: если я записываю целое число в файл в двоичном режиме, c / c ++ запишет 4 байта независимо от значения, сохраненного в этом целом числе. PHP запишет в файл простое целочисленное значение, то есть 0, если значение равно 0, и 100, если оно равно 100. Это вызывает проблемы при использовании поиска, потому что я не знаю определенного количества байтов для перемещения указателя пути. Или в этом случае я пишу символьные массивы фиксированной длины = 25. Как я могу сделать это в php, поскольку переменные вообще не имеют типа?

Ответы [ 2 ]

1 голос
/ 27 декабря 2011

PHP обеспечивает доступ к двоичным файлам.Используйте fopen() и укажите 'b' в поле режима.

Чтобы выполнить произвольный доступ (т. Е. Чтение / запись), вы должны указать 'r+' в поле режима (или 'w+', 'x+' или 'a+', в зависимости от того, что именно вы хотите сделать).

Чтобы записать двоичные данные (а не текстовые представления этих данных), используйте fwrite() и pack().

0 голосов
/ 27 декабря 2011

Из php документации :

Напротив, вы также можете использовать «b» для принудительного запуска двоичного режима, который не будет переведите ваши данные. Чтобы использовать эти флаги, укажите «b» или «t» как последний символ параметра режима.

Что именно вы имеете в виду, когда говорите, что php не предоставляет доступ к двоичным файлам?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...