2016-08-18 2 views
4

Задайте массив, а затем отсортируйте его, чтобы сделать вероятность появления до появления. Итак, я написал метод, как показано ниже в Swift. Я не вижу ничего плохого в этих методах, но логика просто неправильная. Любой может дать мне ключ, который спасет мою жизнь. Спасибо заранее!Сортируйте массивы, чтобы сделать коэффициенты перед evens

Вот код:

class OddsBeforeEvens { 
    func sortArrayOddsBeforeEvens(var array: [Int]) -> [Int]? { 
     if array.isEmpty { return nil } 
     let length = array.count 
     var begin = 0 
     var end = length - 1 
     var temp: Int 
     while (begin < end) { 
      while (begin < end && array[begin]/2 != 0) { 
       begin += 1 
      } 
      while (begin < end && array[end]/2 == 0) { 
       end -= 1 
      } 
      if (begin < end) { 
       temp = array[begin] 
       array[begin] = array[end] 
       array[end] = temp 
      } 
     } 

     return array 
    } 
} 
+2

Вы пытались * отладить * код? –

+1

Кажется, что вам нужно использовать '% 2! = 0' вместо'/2! = 0', чтобы определить, является ли число нечетным или четным. –

+0

@ Хоа, большое спасибо! Я совершил ужасную элементарную ошибку, и я долго не узнал! Спасибо!!!! –

ответ

4

В качестве альтернативу, вы можете разделить коэффициенты и четные числа на две операции filter на массив, и просто соединить два полученных массивов, с нечетными значениями массивов до четного значения массива

func sortArrayOddsBeforeEvens(array: [Int]) -> [Int] { 
    let odds = array.filter{ $0 % 2 != 0 } 
    let evens = array.filter{ $0 % 2 == 0 } 
    return odds + evens 
}  

print(sortArrayOddsBeforeEvens([1,4,3,7,8,11,12,27,18])) 
// [1, 3, 7, 11, 27, 4, 8, 12, 18] 

Или

func sortArrayOddsBeforeEvens(array: [Int]) -> [Int] { 
    return array.filter{ $0 % 2 != 0 } + array.filter{ $0 % 2 == 0 } 
}  

print(sortArrayOddsBeforeEvens(array: [1,4,3,7,8,11,12,27,18])) 
// [1, 3, 7, 11, 27, 4, 8, 12, 18] 

Это не должно быть проблемой на практике, если вы» перезапись некоторых приложений HPC (в этом случае Swift не является оптимальным языком выбора), но если вы почему-то беспокоитесь о производительности wr.t. две операции filter, вы можете использовать результат $0 % 2 (который всегда находится в наборе {0, 1}) непосредственно в качестве индекса, чтобы указать на один из двух заданных массивов результатов. Например.

func sortArrayOddsBeforeEvens(array: [Int]) -> [Int] { 
    var arr: [[Int]] = [[],[]] 
    array.forEach { arr[$0 % 2].append($0) } 
    return arr[1] + arr[0] 
} 

print(sortArrayOddsBeforeEvens([1,4,3,7,8,11,12,27,18])) 
// [1, 3, 7, 11, 27, 4, 8, 12, 18] 
+1

Это замечательно! Я буду держать это в голове! Спасибо, что поделились! –

3

Вы можете использовать sort функцию быстры, как это:

let arr = [1,3,4,5,9,10,50,2,8,12,34,53,88,23] 

let arrSorted = arr.sort { (a, b) -> Bool in 
    return a % 2 != 0 
} 

получить отсортированные шансы и упорядоченные эвенов:

let arrSorted = arr.sort { (a, b) -> Bool in 
    if (a % 2 != 0) { 
     if (b % 2 != 0) { 
      return a < b 
     } else { 
      return true 
     } 
    } else { 
     return a < b 
    } 
} 
+0

Это может работать случайно, но ваша функция сравнения не является «строгим слабым порядком» по мере необходимости: https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_MutableCollectionType_Protocol/index.html#// apple_ref/swift/intfm/MutableCollectionType/s: FEsPs21MutableCollectionType4sortFFTWx9Generator7Element_WxS0_S1 ___ SbGSaWxS0_S1___ –

+0

О, спасибо, за ваш комментарий! –

4

Вдохновленный ответ Хоа, вот метод сортировки, который обеспечит вам «strict weak ordering». В результате у вас будут все нечетные значения до тех пор, пока они не будут. И внутри каждой группы значения будут отсортированы.

let arr = [1,3,4,5,9,10,50,2,8,12,34,53,88,23] 

let arrSorted = arr.sort { (a, b) -> Bool in 
    // If a and b are both even (or odd), we simply compare them 
    if a % 2 == b % 2{ 
     return (b>a) 
    } 
    // Else, we just put the odd values first 
    return a % 2 != 0 
} 

Этот пример дает этот результат:

[1, 3, 5, 9, 23, 53, 2, 4, 8, 10, 12, 34, 50, 88] 
2

В то время как решение @dfri «ы хорошо работает и выглядит намного лучше, чем у меня, производительность 2n, а это означает, что фильтр перебирает массива в два раза. Если вы после исполнения, вы можете использовать этот код, потому что он только циклически проходит через массив один раз, поэтому он должен быть в два раза быстрее.

func sortArrayOddsBeforeEvens(array: [Int]) -> [Int] { 
    var odds = [] 
    var evens = [] 
    for int in array { 
     if int % 2 == 0 { 
      evens.append(int) 
     } else { 
      odds.append(int) 
    } 
    return odds + evens 
} 
+0

Это не будет сортировать числа от самых маленьких до самых больших. – WMios

+1

который не запрошен OP – Yannick

+0

Я имел в виду это, как и в, конечно, ваш будет быстрее, когда он не сделает то же самое. Не пытался сказать, что вы сделали это неправильно - на самом деле, вероятно, именно то, что ищет OP. – WMios

Смежные вопросы