LINUX.ORG.RU

Узнать, содержится ли один диапазон в другом на Си

 , ,


1

4

Сразу скажу что задача можно считать учебная и ответ на неё многих может показаться банальным, но мне интересно как бы вы её решили.

Условие очень простое: выражение is_contained(h0, hlen, q0, qlen) должно возвращать 1, если диапазон под вопросом (question - q), начинающийся включительно с q0 и занимающий всего qlen индексов, полностью содержится в диапазоне (have - то что имеется), начинающимся включительно с h0 и имеющим длину в hlen индексов, и должно возвращать 0 во всех других случаях. Оба диапазона относятся к индексам некоего массива или смещениям байт в файле, при том что файл целиком влез в аллоцированный блок памяти процесса в виде того же массива.

Вопрос: написать синтаксически корректную (допустим C89) реализацию функции is_contained(), такую чтобы всегда отдавала правильный результат, при этом не содержала лишнего кода и не требовала линковки с чем-то ещё, включая libc, для работы (но содержимым C89-стандартных (только их) .h файлов пользоваться можно, если оно не приводит к импорту символов извне).

Условие именно такое как я написал, никакие уточнения не предполагаются. Если считаете что условие где-то двусмысленное - дополняйте его как хотите (не противореча исходным утверждениям).

★★★★★

Последнее исправление: firkax (всего исправлений: 5)

Ответ на: комментарий от beastie

Хоть бы тесты привёл, чесслово.

Я специально указал, что условие уточнениям не подлежит. Хотя, пожалуй, я там пропустил слово «полностью», виноват, сейчас исправлю, а то и правда немного двусмысленно.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
#include <stdio.h>
#include <stdbool.h>

bool is_contained(int h0 [], size_t hlen, int q0 [], size_t qlen){
    for(int i = 0; i < hlen - qlen; i++){
        bool match = true;
        for(int j = 0, k = i; j < qlen; j++, k++){
            if( q0[j] != h0[k]){
                match = false;
                break;
            }
        }
        if(match) return true;
    }
    return false;   
}

int main(){
    int have [] = {0,1,2,3,4,5,6,7,8,9};
    int question [] = {4,5,6};

    bool result = is_contained(have, sizeof(have)/sizeof(int), question, sizeof(question)/sizeof(int));

    if(result) printf ("got it!");
    else printf ("ups"); 
}


got it!

такое?

olelookoe ★★★
()

Условие очень простое: выражение is_contained(h0, hlen, q0, qlen) должно возвращать 1, если диапазон под вопросом (question - q), начинающийся включительно с q0 и занимающий всего qlen индексов, полностью содержится в диапазоне (have - то что имеется), начинающимся включительно с h0 и имеющим длину в hlen индексов, и должно возвращать 0 во всех других случаях. Оба диапазона относятся к индексам некоего массива или смещениям байт в файле, при том что файл целиком влез в аллоцированный блок памяти процесса в виде того же массива.

За такую формулировку мне кажется, что нужно отправлять на пенсию(по инвалидности).

arax ★★
()
Ответ на: комментарий от beastie

Диапазоны индексов же. Впрочем, если под текст условия можно непротиворечиво подогнать другое - тоже годится.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)

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

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 3)
Ответ на: комментарий от wandrien

У вопроса единственная проблема это косноязычная формулировка, а в твоём ответе (когда ты его дополнишь до функции) скорее всего будет как минимум один баг (который никакими уточнениями вопроса не превратить в простительный).

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)

А в чём смысл этого задания?Проверить знание с89 и целочисленного сложения?

(но содержимым C89-стандартных (только их) .h файлов пользоваться можно, если оно не приводит к импорту символов извне)

Лол, только программисты пишут текст в скобхах внутри текста в скобках. Не надо так.

dsxl
()
Ответ на: комментарий от dsxl

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

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

эх )

-std=c89

#define bool int
#define true  1
#define false !true

bool is_contained(int h0 [], size_t hlen, int q0 [], size_t qlen){
    int i,j,k;
    for(i = 0; i < hlen - qlen; i++){
        bool match = true;
        for(j = 0, k = i; j < qlen; j++, k++){
            if( q0[j] != h0[k]){
                match = false;
                break;
            }
        }
        if(match) return true;
    }
    return false;   
}

так пойдет? )

olelookoe ★★★
()
Ответ на: комментарий от olelookoe

В плане кода - пойдёт, но по-моему она не подходит под условие, ведь там сказано про диапазоны а не множества.

edit: Хотя нет, у тебя тоже баг.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от wandrien

Так ты ответ не привёл. И всего 3 участника не интересно, я надеюсь кто-то таки решит ещё корректно.

firkax ★★★★★
() автор топика
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

Чтобы что-то решить корректно, нужно поставить задачу корректно. А текущая постановка задачи выглядит, как ТЗ из которого выкинули код, на словах попросили передать, что нужно сделать рекрутеру, который в программировании, что слон в металлургии, а рекрутер уже вот такое задание дал на собеседовании, и потом отдает код обратно программистам на проверку…

С такой постановкой задачи, вначале нужно обсуждать (выпытывать) четкое условие, с фискированными типами данных, аннотированием функции и ограничениями на входные параметры, а потом уже решение в виде кода предлагать.

soomrack ★★★★
()
Ответ на: комментарий от olelookoe

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

кстати по сабжу темы,

uint8_t is_contained(const char *h0, size_t hlen, const char *q0, size_t qlen) {
  return (q0 >= h0) && ((q0 + qlen) <= (h0 + hlen));
}
Lrrr ★★★★★
()
Ответ на: комментарий от soomrack

Нет. Ты не понял сути задачи просто. Она не в том, чтобы закодить по факту готовый алгоритм только дали тебе его на словах, а сделать надо на Си. Она в том, что требуется выполнять сформулированный бытовым языков функционал и делать это на 100% «без багов», а уж какие там проблемы могут всплыть - должен как раз выяснить исполнитель, и все их преодолеть. Типы данных я специально не указал - их требуется выбрать и не сделать в этом выборе ошибку. Собственно, такая косноязычная формулировка получилась как раз из желания спрятать прототип, но так, чтобы казалось будто это случайно вышло.

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

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

soomrack ★★★★
()

С нетерпением жду ответа от ТС с пояснением подводных камней, потому что викторины это всегда интересно, а если это ещё и гонки (предположительно) здоровых людей на инвалидной коляске (Си), то потеха обеспечена 😁.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от soomrack

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

firkax ★★★★★
() автор топика
Ответ на: комментарий от firkax

ctime на юниксах хранит время изменения метаданных (права доступа, владелец, число хард линков). А на винде - время создания.

Логично предположить, что собранные для unix-like прикладные программы не должны это поле описывать как Created. Но они описывают)

Не все, но многие.

wandrien ★★
()