Отформатировать дробь в сборщике до наименьшего общего знаменателя?

Ниже показано, как я форматирую свой сборщик в настоящее время. Я бы очень хотел, чтобы он показывал 1/8 вместо 2/16 или 1/2 вместо 8/16. Как я могу настроить это, чтобы показать желаемый результат? Спасибо!

fractionArray = [[NSMutableArray alloc] init];
for(int frac = 0; frac <= 15; frac ++){ 
    NSString *fracString = [NSString stringWithFormat:@"%d/16", frac];
    [fractionArray addObject:fracString]; // Add the string.

person Jason    schedule 24.04.2012    source источник
comment
возможный дубликат Преобразовать десятичную дробь в дробь в Objective-C?. Смотрите второй ответ.   -  person CodaFi    schedule 24.04.2012
comment
Это чтобы преобразовать десятичную, а не фракцию...?   -  person Jason    schedule 24.04.2012
comment
Вы можете легко перейти к решению, получив два необходимых аргумента с помощью -componentsSeparatedByString:. Не сбрасывайте со счетов ценность второго ответа так легко.   -  person CodaFi    schedule 24.04.2012
comment
Если вы сможете привести пример на этой странице, я с радостью закрою этот пост. Я явно не такой продвинутый, как ты. Я учусь, видя код, а затем понимая, как он работает.   -  person Jason    schedule 24.04.2012


Ответы (2)


Современные дети... алгоритм Евклида... чему учат в школе ... ворчать ворчать...

int gcd(int a, int b) {
    // assumes a >= 0 && b > 0
    while (b != 0) {
        int t = a % b;
        a = b;
        b = t;
    }
    return a;
}

NSString *stringByReducingFraction(int a, int b) {
    if (a == 0) return @"0";
    if (a == b) return @"1";

    int g = gcd(a, b);
    return [NSString stringWithFormat:@"%d/%d", a / g, b / g];
}
person rob mayoff    schedule 24.04.2012
comment
Ха! Конечно! Мое оправдание, что я не помню, что я никогда не использую gcd() ни для чего. С другой стороны, GCD очень полезен. :) - person davehayden; 25.04.2012
comment
В этом коде есть ошибки, я не знаю, с чего начать, исправляя это. - person Jason; 30.04.2012
comment
В коде, который я разместил, нет ошибок. Я разместил полный рабочий пример и его вывод по адресу gist.github.com/2553024. - person rob mayoff; 30.04.2012
comment
Итак, как мне применить это к моему коду выше? Потому что с вашим я получаю 7 предупреждений и 7 ошибок. Даже не знаю, с чего начать их исправлять. - person Jason; 30.04.2012
comment
Я помещаю свой код выше в viewDidLoad, это моя проблема? - person Jason; 30.04.2012
comment
Мой код выше определяет две функции. Вы не помещаете определения функций в определения методов. Похоже, вам нужно освежить в памяти основы C и Objective-C. - person rob mayoff; 30.04.2012
comment
Я никогда не ходил на какие-либо курсы, я изучаю все это в свое личное и личное время. Этот сайт дал мне больше знаний, чем любой учебник, который я читал. Я учусь, видя, как работает код, и тогда я могу понять его более четко. Спасибо за вашу помощь! - person Jason; 05.05.2012

Это должно работать для любой степени 2 знаменателя:

// dodge this special case:
[fractionArray addObject:@"0"];

for ( int numerator = 1; numerator <= 15; numerator++ )
{
    int denominator = 16;
    int num = numerator;

    while ( num % 2 == 0 )
    {
        num /= 2;
        denominator /= 2;
    }

    NSString *fracString = [NSString stringWithFormat:@"%d/%d", num, denominator];
    [fractionArray addObject:fracString]; // Add the string.
}

И это легко распространить на любой знаменатель. (Подсказка: замените 2 на n, повторите n от 2 до sqrt (знаменатель).)

РЕДАКТИРОВАТЬ: на самом деле работает сейчас!


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

int denominator = 240;

for ( int numerator = 1; numerator < denominator; numerator++ )
{
    int denom = denominator;
    int num = numerator;
    int factor = 2;

    while ( factor * factor < denom )
    {
        while ( (num % factor) == 0 && (denom % factor) == 0 )
        {
            num /= factor;
            denom /= factor;
        }

        // don't worry about finding the next prime,
        // the loop above will skip composites
        ++factor; 
    }

    NSString *fracString = [NSString stringWithFormat:@"%d/%d", num, denom];
    [fractionArray addObject:fracString];
}
person davehayden    schedule 24.04.2012
comment
Сбои в NSString *fracString = [NSString stringWithFormat:@%d/%d, числитель, знаменатель]; - person Jason; 24.04.2012
comment
Ага, тупоголовый: если мы разделим числитель на 2, то это испортит цикл. Я отредактирую ответ. :) - person davehayden; 24.04.2012
comment
@davehayden Верхний код работает, но отображается как 0, 1/16, 1/8, 3/16, 1/4, 5/16, 3/8, 7/16, 1/2, 9/16, 5. /8, 11/16, 3/4, 13/16, 7/8, 15/16, 1/16, 0 и т. д., а затем после 15/16 отображается 2/16. Итак, после каждого дюйма, после 15/16 он продолжает идти 3/16, 4/16 и т. д. - person Jason; 26.04.2012
comment
Итак, я думаю, мне не нужен цикл, так как его нужно запустить только один раз...? - person Jason; 26.04.2012
comment
Нет-нет, у Роба Мейоффа есть правильный ответ: просто найдите НОД (наибольший общий делитель) числителя и знаменателя, а затем разделите их на это число. Быстрее, чище, лучше во всем! - person davehayden; 26.04.2012
comment
@davehayden Я получаю сумасшедшие ошибки с ответом Роба, я даже не знаю, с чего начать их исправлять. - person Jason; 30.04.2012