버전비교

A씨는 두 개의 버전을 비교하는 프로그램을 작성해야 한다.

버전은 다음처럼 "." 으로 구분된 문자열이다.

버전 예) 1.0.0, 1.0.23, 1.1

두 개의 버전을 비교하는 프로그램을 작성하시오.

다음은 버전 비교의 예이다.

0.0.2 > 0.0.1
1.0.10 > 1.0.3
1.2.0 > 1.1.99
1.1 > 1.0.1
lexicographical order
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

55개의 풀이가 있습니다. 1 / 6 Page

파이썬입니다

from itertools import zip_longest

def compare(left, right):
    left_vars = map(int, left.split('.'))
    right_vars = map(int, right.split('.'))
    for a, b in zip_longest(left_vars, right_vars, fillvalue = 0):
        if a > b:
            return '>'
        elif a < b:
            return '<'
    return '='

CASES = [['0.0.2', '0.0.1'],
         ['1.0.10', '1.0.3'],
         ['1.2.0', '1.1.99'],
         ['1.1', '1.0.1']]

if __name__ == '__main__':
    for case in CASES:
        print('{0[0]} {1} {0[1]}'.format(case, compare(*case)))
zip_longest가 있었군요. 배워갑니다 - 이진환, 2015/12/30 09:18 M D
zip_longest가 우용하네요^^ 부등호를 리턴하는 생각이나 문자열 포맷으로 깔끔하게 마무리하는게 인상적입니다. - 디디, 2016/03/19 23:46 M D
부등호에 대한 리턴은 생각하지 못했는데. 배워갑니다.~ - 진평수, 2017/02/21 17:37 M D
덕분에 itertools 에 대하여 정리하였습니다. 반복형데이타를 다룰때 정말 유용한 라이브러리이네요. 특히 '순열과 조합'을 쉽게 다룰 수 있는 것을 알았습니다. 고맙습니다. - 예강효빠, 2017/05/03 01:44 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

C# 입니다.

static char[] separ = { '.' };
const int ERROR = 100;

static void Main(string[] args)
{
    string v1 = "0.0.1", v2 = "0.0.1.0.0.1";    
    switch (CompareVersion(v1, v2))
    {
        case -1: Console.Write(string.Format("{0} < {1}", v1, v2)); break;               
        case 0: Console.Write(string.Format("{0} == {1}", v1, v2)); break;
        case 1: Console.Write(string.Format("{0} > {1}", v1, v2)); break;
        case ERROR: Console.Write("Invalid Version"); break;
    }
}

static int CompareVersion (string v1, string v2)
{           
    string[] v1a = v1.Split(separ, StringSplitOptions.RemoveEmptyEntries);
    string[] v2a = v2.Split(separ, StringSplitOptions.RemoveEmptyEntries);

    if (v1a.Length == 0 || v2a.Length == 0) return ERROR;
    int maxLength = v1a.Length > v2a.Length ? v1a.Length : v2a.Length;

    for (int i = 0; i < maxLength; i++)
    {
        int v1i = 0, v2i = 0;
        if (v1a.Length > i && !int.TryParse(v1a[i], out v1i)) return ERROR;
        if (v2a.Length > i && !int.TryParse(v2a[i], out v2i)) return ERROR;
        if (v1i != v2i) return v1i.CompareTo(v2i);
    }
    return 0;
}

다른 효율적인 방법이 있는지는 모르겠지만, 별다른 기법 없이 문자열 나누고 앞부분부터 하나씩 비교했습니다 공백이 들어가거나, 동일한버전이지만 길이가 다를경우도 문제없이 비교됩니다. 숫자외의 다른 문자열을 넣거나 비어있다면 오류 메시지를 날립니다. 예제의 결과는 v2가 더 크다고 처리됩니다. 혹시나 개행하고 싶다면 그건 기분 탓일겁니다.

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

파이썬 입니다. 만약 서브 버전이 없는 경우 기본적으로 0 이라는 가정하에 비교하도록 하였습니다.

def CompareVersion (version1, version2) :

    v1 = map(int, version1.split('.'))
    v2 = map(int, version2.split('.'))

    if len(v1) > len(v2):
        v2 += [0] * (len(v1) - len(v2))
    else:
        v1 += [0] * (len(v2) - len(v1))

    for (vv1, vv2) in zip(v1, v2):
        if vv1 > vv2:
            return 1
        elif vv1 < vv2:
            return -1

    return 0

print CompareVersion ('0.0.2',  '0.0.1')
print CompareVersion ('1.0.3',  '1.0.10')
print CompareVersion ('1.2.0',  '1.1.99')
print CompareVersion ('1.1',    '1.0.1')
print CompareVersion ('1.1',    '1.1.0.1')
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
def versionCmp(a,b):
    a,b=map(lambda x : map(int, x.split('.')),(a,b))
    return a>b


print versionCmp('0.0.2','0.0.1') 
print versionCmp('1.0.10','1.0.3') 
print versionCmp('1.1.99','1.2.0') 
print versionCmp('1.1','1.0.1') 

라고 작성하였으나... 버그가 있어서 수정하였습니다. 버전 1과 1.0을 다르게 인식하더군요. 또한 버전이 같은 경우를 따로 표시하고, 위 버그를 해결하였습니다. 앞버전이 높으면 1, 같으면 0, 낮으면 -1을 출력합니다.

def versionCmp(a,b):
    a,b=map(lambda x : map(int, x.split('.')),(a,b))
    while len(a)>len(b): b += (0,)
    while len(a)<len(b): a += (0,)
    return cmp(a,b)


print versionCmp('0.0.2','0.0.1') # 1
print versionCmp('1.0.10','1.0.3') # 1
print versionCmp('1.1.99','1.2.0') # -1
print versionCmp('1.1','1.0.1') # 1
print versionCmp('1.0','1.0.0') # 0
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

java입니다. 출제자님 문제상의 예외사항이 있어 추가하여 구현해보았습니다.

import java.util.Scanner;

public class version_comp {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String v1, v2, tmp;
        String[] v1_arr, v2_arr;
        String in_param[];

        while(true){
            System.out.println("Input compared version : ");
            v1 = sc.nextLine();
            if(v1.length() != 0)
            {
                v1_arr = v1.split("[.]");
                break;
            }
            else
            {
                System.out.println("Invalid value!!");
            }
        }

        while(true){
            System.out.println("Input comparing version : ");
            v2 = sc.nextLine();
            if(v2.length() != 0)
            {
                v2_arr = v2.split("[.]");
                break;
            }
            else
            {
                System.out.println("Invalid value!!");
            }
        }

        switch (compare(v1_arr, v2_arr)) {
        case 0:
            System.out.println(v1+" < "+v2);
            break;

        case 1:
            System.out.println(v1+" > "+v2);
            break;

        case -1:
            System.out.println(v1+" == "+v2);
            break;
        }
    }

    static int compare(String[] v1, String[] v2)
    {
        int ret = -1;

        for(int i = 0 ; i < v1.length ; i++){
            if(v2.length-1 >= i)
            {
                if(Integer.parseInt(v1[i]) < Integer.parseInt(v2[i]))
                {
                    ret = 0;
                    break;
                }
                else if(Integer.parseInt(v1[i]) > Integer.parseInt(v2[i]))
                {
                    ret = 1;
                    break;
                }   
            }
            else
                ret = 1;
        }

        if(v1.length < v2.length)
            ret = 0;

        return ret;
    }
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
파이썬 2.7


v1 = '0.1.2'
v2 = '0.2'

size = len(v1)

for i in range(size):
    if v1[i] > v2[i]:
        recent_ver = v1
        break
    elif v1[i] < v2[i]:
        recent_ver = v2
        break
    else:
        continue

print 'recent version : ', recent_ver
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
v1 = '1.2.0'
v2 = '1.1.99'

v1_array = v1.split('.')
v2_array = v2.split('.')

for x in range(len(v1_array)):
    if int(v1_array[x]) > int(v2_array[x]):
        print(v1 + ' > ' + v2)
        break
    elif int(v1_array[x]) < int(v2_array[x]):
        print(v2 + ' > ' + v1)
        break
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

Tcl/tk입니다. 이렇게 해도 되나 모르겠네요^^;

proc ver_check {a b} {
    set i "$a $b"
    set oldVer  [ lindex [ lsort -dictionary -increasing $i ] 0 ]
    set lastVer [ lindex [ lsort -dictionary -increasing $i ] 1 ]   
    puts "$lastVer > $oldVer"
}
ver_check 1.1 1.0.1
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

PHP 입니다.

function compVersion ($a, $b) {
    if (!$a || !$b) {
        echo "Need 2 version value for compare";
    }

    $arrA = explode(".", $a);
    $arrB = explode(".", $b);

    $max = sizeof($arrA);
    for ($i = 0; $i < $max; $i++) {
        if ($arrA[$i] == $arrB[$i]) {
            continue;
        }
        if ($arrA[$i] > $arrB[$i]) {
            echo $a . " > " . $b;
            return;
        }
        if ($arrA[$i] < $arrB[$i]) {
            echo $a . " < " . $b;
            return;
        }
    }
    if (sizeof($arrB) > $max) {
        echo $a . " < " . $b;
        return;
    }
    echo $a . " = " . $b;
}

compVersion ("0.0.2", "0.0.1");
compVersion ("1.0.10", "1.0.3");
compVersion ("1.2.0", "1.1.99");
compVersion ("1.1", "1.0.1");
compVersion ("1.1", "1.1.1");
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

Swift 입니다.

import Foundation

extension String {
    public func biggerThan(s2: String) -> Bool {
        let s1Array = self.componentsSeparatedByString(".").map { Int($0)! }
        let s2Array = s2.componentsSeparatedByString(".").map { Int($0)! }
        return zip(s1Array, s2Array).map { $0.0 > $0.1 }.reduce(false) { $0 || $1 }
    }
}

let v1 = "1.1"
let v2 = "1.0.1"

let op: String

if v1 == v2 {
    op = "=="
}
else if (v1.biggerThan(v2)) {
    op = ">"
}
else {
    op = "<"
}

print("\(v1) \(op) \(v2)")
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

※ 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.

lexicographical order x 1

언어별 풀이 현황
전 체 x 55
python x 29
cs x 2
java x 13
기 타 x 7
php x 2
ruby x 1
javascript x 1