2015-11-18 22 views
3

Я создал многомерный массив (срез) в Go следующим образом:Сортировка многомерного массива/срез

var distancematrix [5][5]int 

Так что это 5 * 5 массив/срез. Теперь я вставив значения в этом срезе таким образом, что в точке:

distancematrix : [[0 154 12 35 138] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]] 

Теперь я хочу, чтобы отсортировать этот массив в порядке возрастания, например:

sorteddistancematrix : [[0 12 35 138 154] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]] 

Я попытался sort.Ints(distancematrix[0]), но он бросает говорится об ошибке:

cannot use distancematrix[0] (type [5]int) as type []int in argument to sort.Ints 

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

+1

Вы смесительный термин массив и срез по всему вашему вопросу. Я бы рекомендовал прочитать [эту статью] (https://blog.golang.org/go-slices-usage-and-internals) для некоторых разъяснений. –

+1

Получение наименьшего ненулевого значения не требует сортировки массива, на самом деле это будет довольно расточительно. – chill

ответ

4

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

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

Пример реализации:

func smallestNonZero(s []int) (n int) { 
    for _, v := range s { 
     if v != 0 && (v < n || n == 0) { 
      n = v 
     } 
    } 
    return 
} 

Примечание: Эта функция возвращает 0 тогда и только тогда, когда пропущенный фрагмент не содержит ненулевой элемент (то есть, это либо полный 0 с или это пустой или это nil). Эта функция также работает правильно, если срез (также) содержит отрицательные числа.

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

С его помощью:

fmt.Println(smallestNonZero([]int{5, 3, 1, 4})) 
fmt.Println(smallestNonZero([]int{0, 3, 5, 8, 0, 2, 9})) 
arr := [5]int{0, 154, 12, 35, 138} 
fmt.Println(smallestNonZero(arr[:])) 

Output (попробовать его на Go Playground):

1 
2 
12 
+1

+1 для ключевых точек: 1. массив не нужно сортировать, чтобы найти наименьший элемент, и 2. что сортировочные массивы/срезы обычно намного дороже, чем однопроходный поиск. – gbulmer

+0

Спасибо большое icza :) Это разрешает мой запрос. Кроме того, canyou расскажите мне, как я могу получить индекс наименьшего положительного числа? Как я попытался это: FUNC smallestNonZeroIndex (с [] Int) (п Int) { \t вар я Int \t для I, V: = диапазон s { \t \t, если v> 0 && (v <п || п == 0) { \t \t \t п = v \t \t \t я ++ \t \t} \t} \t возвращение я } но она возвращает 0 всегда. Заранее спасибо .. –

+0

@fnaticRCggwp Если вы используете 'for range', вам не следует увеличивать переменную цикла' i', поскольку она автоматически увеличивается/внутренне. Просто скопируйте мой код из ответа. – icza

1

The Go Programming Language Specification

Slice expressions

Slice выражение построить подстроку или фрагмент из строки, массива, указателя на массив или ломтик. Существует два варианта: простая форма, которая определяет нижнюю и верхнюю границы и полную форму, которая также указывает на , связанный с емкостью.

Простой срез выражения

Для строки, массива, указатель на массив, или ломтик, первичный выражение

a[low : high] 

строит подстроку или срез. Индикаторы low и high выбирают, какие элементы операнда a появляются в результате. Результат имеет индексы , начиная с 0 и длины, равной максимуму - низкому. После нарезки массива

a := [5]int{1, 2, 3, 4, 5} 
s := a[1:4] 

срез имеет тип с [] INT, длиной 3, емкостью 4 и элементов

s[0] == 2 
s[1] == 3 
s[2] == 4 

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

a[2:] // same as a[2 : len(a)] 
a[:3] // same as a[0 : 3] 
a[:] // same as a[0 : len(a)] 

Если указатель на массив, а [низкая: высокая] является сокращением (* а) [низкая : высокая].

Для преобразования типа [5]int в тип []int, нарежьте массив. Например,

package main 

import "sort" 

func main() { 
    var distancematrix [5][5]int 
    sort.Ints(distancematrix[0][:]) 
} 
-1

вар distancematrix [5] [5] INT, создаст многомерный массив срез 5 * 5 междунар. И когда вы пытаетесь получить доступ к distancematrix [0], он возвращает int array slice типа [5] int. Где в виде sort.Ints ожидает тип [] int.

Ниже приведена матрица расстояний типа [] [], и поэтому distancematrix [0] возвращает массив срезов типа [] int.

package main 

import (
    "fmt" 
    "sort" 
) 

func main() { 
    distancematrix := [][]int{{0, 154, 12, 35, 138}, {0, 0, 0, 0, 0}} 
    sort.Ints(distancematrix[0]) 
    fmt.Println(distancematrix[0]) 
} 
+0

Не можете добавить комментарий к вашему коду? – M4ks

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