Write code of checking whether given string is palindrome


Environment and Prerequisite

  • Python
  • C++


What is Palindrome?

  • Palindrome is a string which reads the same backward as forward.
  • Example: 토마토, abdba, 토마토맛토마토, 1234567654321


Code

  • Time Complexity: O(n)


C


#include <stdio.h>
#include <string.h>

int is_palindrome(char * s){

	int len = strlen(s);

	int left = 0;
	int right = len-1;


	// move left one and right one to middle one by one
	// (right - left) > 1
	// [In case of odd number] left only middle element
	// [In case of even number] go until "left + 1==right"
	while ( (right - left) > 1 ) {

		if( s[right] != s[left] ){
			return 0;
		}
		left += 1;
		right -= 1;
	}

	return 1;

}


int main (){


	char * palindrome = "abcdcba";
	char * non_palindrome = "abcdefg";

	printf("%d\n", is_palindrome(palindrome));
	printf("%d\n", is_palindrome(non_palindrome));

	return 0;

}


C++


#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

bool is_palindrome(string s){

	string s_reverse = s;
	reverse(s_reverse.begin(), s_reverse.end());
	return s == s_reverse ? true : false;

}


int main (){

	string s1 = "abcde1edcba";
	string s2 = "asdlkfjaw;oefjao;iwefja;ow";

	cout << is_palindrome(s1) << '\n';
	cout << is_palindrome(s2) << '\n';

	return 0;

}


Python


def is_palindrome(s):
	return s == s[::-1]


s1 = "abcde1edcba"
s2 = "fjaw;"

print(is_palindrome(s1))
print(is_palindrome(s2))


Reference

Go언어에서 구조체(struct)와 메소드(method)의 기본적인 사용법을 정리해보자


환경

  • Go(1.15.8)
  • 다른 프로그래밍 언어 사용 경험


구조체(struct)와 메소드(method)

Go에서의 구조체(struct)

  • Go에서는 자기만의 방식으로 OOP를 지원한다. 여기서 신기하게도 기존에 흔하게 사용하는 class가 없다고 한다. class가 없기에 상속도 없다.
  • 그래서 구조체(struct)와 메소드(method)를 사용한다.
  • 아래에서는 이제 간단하게 구조체(struct)의 사용법과 그에 사용되는 메소드(method)에 대해 알아본다.


구조체(struct) 예시

  • 아래처럼 4가지 방법이 사용가능하다.
  • 기존 예약어인 new를 사용할수도 있고 생성자 함수를 만들수도 있다.
package main

import (
    "fmt"
)

// define struct
type Rectangle struct {
    width int
    height int
}

// define constructor
func NewRectangle(width int, height int) *Rectangle{
    return &Rectangle{width, height}
}

func main() {

    // create instances
    var rec1 = Rectangle{}
    rec1.width = 2
    rec1.height = 3

    rec2 := Rectangle{4, 5}

    var rec3 = new(Rectangle)
    rec3.width = 6
    rec3.height = 7

    var rec4 = NewRectangle(8, 9)

    // check instances
    fmt.Println(rec1.width, rec1.height)
    fmt.Println(rec2.width, rec2.height)
    fmt.Println(rec3.width, rec3.height)
    fmt.Println(rec4.width, rec4.height)
}
2 3
4 5
6 7
8 9


메소드(method) 예시

  • 리시버(Receiver)를 통해 어떤 구조체(struct)의 메소드인지 명시가 가능하다.
  • Value 리시버와 Pointer 리시버가 있다.
  • 아래 예제에서는 (r Rectangle)(r *Rectangle)가 리시버(Receiver)다.
package main

import (
    "fmt"
)

// define struct
type Rectangle struct {
    width int
    height int
}

// define constructor
func NewRectangle(width int, height int) *Rectangle{
    return &Rectangle{width, height}
}

// define methods
func (r Rectangle) area() int{
    return r.width * r.height
}

// pointer receiver
func (r *Rectangle) setWidth(width int){
    r.width = width
}

// value receiver
func (r Rectangle) setHeight(height int){
    r.height = height
}

func main() {

    // create instances
    var rec = NewRectangle(8, 9)

    // check instances
    fmt.Println(rec.width, rec.height)
    fmt.Println()

    // check methods
    fmt.Println(rec.area())
    fmt.Println()

    rec.setWidth(10)
    // rec.height would not changed because its method's receiver is value receiver
    rec.setHeight(10)
    fmt.Println(rec.width, rec.height)
}
8 9

72

10 9


참고자료

Post about basic usage of struct and method in Go language


Environment and Prerequisite

  • Go(1.15.8)
  • Experience with other programming languages


Struct and Method

Struct in Go

  • Go language supports its own way of OOP. There is no class in Go. Also no class so no inheritance.
  • So it use struct and method.
  • Briefly write about struct and method in below.


Struct Example

  • There are four ways like below example.
  • We can use keyword new or we can make constructor function.
package main

import (
    "fmt"
)

// define struct
type Rectangle struct {
    width int
    height int
}

// define constructor
func NewRectangle(width int, height int) *Rectangle{
    return &Rectangle{width, height}
}

func main() {

    // create instances
    var rec1 = Rectangle{}
    rec1.width = 2
    rec1.height = 3

    rec2 := Rectangle{4, 5}

    var rec3 = new(Rectangle)
    rec3.width = 6
    rec3.height = 7

    var rec4 = NewRectangle(8, 9)

    // check instances
    fmt.Println(rec1.width, rec1.height)
    fmt.Println(rec2.width, rec2.height)
    fmt.Println(rec3.width, rec3.height)
    fmt.Println(rec4.width, rec4.height)
}
2 3
4 5
6 7
8 9


Method Example

  • By using receiver, we can define method for specific class.
  • There are value receiver and pointer receiver.
  • In below example, (r Rectangle) and (r *Rectangle) are receivers.
package main

import (
    "fmt"
)

// define struct
type Rectangle struct {
    width int
    height int
}

// define constructor
func NewRectangle(width int, height int) *Rectangle{
    return &Rectangle{width, height}
}

// define methods
func (r Rectangle) area() int{
    return r.width * r.height
}

// pointer receiver
func (r *Rectangle) setWidth(width int){
    r.width = width
}

// value receiver
func (r Rectangle) setHeight(height int){
    r.height = height
}

func main() {

    // create instances
    var rec = NewRectangle(8, 9)

    // check instances
    fmt.Println(rec.width, rec.height)
    fmt.Println()

    // check methods
    fmt.Println(rec.area())
    fmt.Println()

    rec.setWidth(10)
    // rec.height would not be changed because its method's receiver is value receiver
    rec.setHeight(10)
    fmt.Println(rec.width, rec.height)
}
8 9

72

10 9


Reference

Go언어의 기본적인 사용법을 정리해본다.

다른 프로그래밍 언어에 대해서 알고 있다고 가정하고 새로운 언어를 입문하는 내용으로 정리한다.


환경

  • Go(1.15.8)
  • 다른 프로그래밍 언어 사용 경험


설치

Mac

$ go version
go version go1.15.8 darwin/amd64

Ubuntu

  • 파일 다운로드
curl https://golang.org/dl/go1.15.8.linux-amd64.tar.gz -o go1.15.8.linux-amd64.tar.gz
  • 파일 설치
sudo tar -C /usr/local -xzf go1.15.8.linux-amd64.tar.gz
  • /usr/local/go/binPATH 환경변수에 추가
  • 하단처럼 해도 좋으나 ~/.bash_profile이나 ~/.bashrc에 넣어두는 방향이 좋다.
export PATH=$PATH:/usr/local/go/bin


빌드 및 테스트

  • 여기서는 기본 언어의 사용법만 보기에 폴더 구조 생성은 생략한다.

기본 코드 작성

test.go

package main

import "fmt"

func main() {
	fmt.Println("Hello, world!")
}

빌드하고 실행

  • 빌드 후 실행
$ go build test.go
$ ./test
Hello, world!
  • 아래처럼도 가능
$ go run test.go
Hello, world!


사용법

기본 코드 구조

test.go

// package name
// every Go program is made up of packages
// programs start running in package main
package main

// import other packages
import "fmt"

// main function
// it is like "void main()" in C language
func main() {
	fmt.Println("Hello, world!")
}
Hello, world!


변수 선언

특징

  • 기존과 달리 var 변수 타입으로 선언
  • 포인터도 사용할 수 있다.
  • 여러가지 방식으로 아래처럼 선언이 가능하다.
package main

import "fmt"

func main() {
	/*
	variable examples
	*/
	var i int
	i = 1

	var j = 2

	var a,b int
	a = 3
	b = 4

	x := 5

	fmt.Println(i, j, a, b, x)


	/*
	constant examples
	*/

	const c = 10
	const str = "string"

	// multiple constants
	const (
    	visa = "Visa"
    	master = "MasterCard"
    	amex = "American Express"
	)

	fmt.Println(c, str, visa, master, amex)


	/*
	pointer example
	*/

	var ptrVal int = 100
	var ptr *int = &ptrVal

	*ptr = 150

	fmt.Println(ptrVal, *ptr)
}
1 2 3 4 5
10 string Visa MasterCard American Express
150 150


조건문 - if

특징

  • if 다음에 숫자가 아닌 true 또는 false여야 한다.
package main

import "fmt"

func main() {
    testVal := 10

    if testVal % 3 == 1 {
        fmt.Println("Remainder is 1")
    } else if testVal % 3 == 2 {
        fmt.Println("Remainder is 2")
    } else {
        fmt.Println("Remainder is 0")
    }
}
Remainder is 1


조건문 - switch

특징

  • case문 하나를 완료하면 break가 없어도 switch문을 빠져나간다.
  • fallthrough를 이용하면 case문 하나를 완료해도 switch문을 빠져나가지 않고 다음 case를 진행한다.
package main

import "fmt"

func main() {
	var name string
    var category = 2

    switch category {
    case 1:
        name = "Good"
    case 2:
        name = "Very Good"
    case 3, 4: // multiple value can be used in case
        name = "Super Nice"
    default:
        name = "Power"
    }
    fmt.Println(name)
}
Very Good


반복문 - for문

특징

  • for문만 있고 while문이 없으며 for문을 다양하게 지원하기 때문에 while문처럼 쓸 수 있다.
  • continuebreak는 C언어처럼 동일하게 사용 가능하다.
package main

import "fmt"

func main() {

	// basic form
	var sum int = 0

	for i := 1; i < 10; i++ {
		sum += i
	}
	fmt.Println(sum)


	// range usage with array
	names := []string {"김씨", "이씨", "박씨"}

	// index variable is index of array or slice
	for index, name := range names{
		fmt.Println(index, name)
	}


	// for statement with only condition
	sum = 0
	i := 0

	for i < 10 {
		sum += i
		i++
	}
	fmt.Println(sum)
}
45
0 김씨
1 이씨
2 박씨
45


함수

특징

  • 파이썬처럼 반환값이 하나가 여려개가 가능하다.
  • C++처럼 ‘Pass By Reference’가 가능하다.
package main

import "fmt"

func exampleFunc (msg string) {
	fmt.Println(msg)
}

func exampleFuncReturn (msg string) string{
	return msg
}

func exampleFuncReturnMultiple (first int, second int) (int, int){
	return first, second
}

func exampleFuncPassByReference (val *int){
	*val += 10
}

func main() {
	exampleFunc("exampleFunc test")

	fmt.Println(exampleFuncReturn("exampleFuncReturn test"))

	a,b := exampleFuncReturnMultiple(3, 4)
	fmt.Println(a, b)

	var testVal int = 100
	exampleFuncPassByReference(&testVal)
	fmt.Println(testVal)
}
exampleFunc test
exampleFuncReturn test
3 4
110


익명함수

특징

  • 변수에 함수를 할당할 수 있으며 함수명이 없는 익명함수가 사용 가능하다.
package main

import "fmt"

func main() {

    sum := func (values []int) int {
        res := 0
        for _, val := range values {
            res += val
        }
        return res
    }

    fmt.Println(sum([]int {1, 2, 3}))


    sum2 := func (values ... int) int {
        res := 0
        for _, val := range values {
            res += val
        }
        return res
    }

    fmt.Println(sum2(1, 2, 3))
}
6
6


배열

package main

import "fmt"

func printResult(values [3]int) {

    for _, val := range values{
        fmt.Println(val)
    }
    fmt.Println()
}

func main() {

    var arr1 [3]int
    arr1[0] = 1
    arr1[1] = 2
    // arr1[2] will be 0 it is default value

    var arr2 = [3] int {1, 2, 3}
    var arr3 = [...] int {1, 2, 3}

    printResult(arr1)
    printResult(arr2)
    printResult(arr3)
}
1
2
0

1
2
3

1
2
3

슬라이스(Slice)

특징

  • 동적으로 사용할 수 있는 배열로 추가, 병합, 복사 그리고 부분 슬라이싱이 가능하다.
package main

import "fmt"

func main() {

    var sliceExample []int   
    sliceExample = []int{1, 1, 1}
    // also same as below
    // sliceExample := make([]int, 3, 1)


    // append
    sliceExample = append(sliceExample, 2)
    sliceExample = append(sliceExample, 3, 4, 5)
    fmt.Println(sliceExample)
    fmt.Println()


    // append slices
    sliceExampleA := []int{1, 2, 3}
    sliceExampleB := []int{4, 5, 6}
    fmt.Println(append(sliceExampleA, sliceExampleB...))
    fmt.Println()


    // sub-slice
    sliceExample  = []int{1, 2, 3, 4, 5}
    fmt.Println(sliceExample[:]) // 1 2 3 4 5
    fmt.Println(sliceExample[2:]) // 3 4 5
    fmt.Println(sliceExample[:4]) // 1 2 3 4
    fmt.Println(sliceExample[2:4]) // 3 4
}
[1 1 1 2 3 4 5]

[1 2 3 4 5 6]

[1 2 3 4 5]
[3 4 5]
[1 2 3 4]
[3 4]


맵(Map)

특징

  • 맵(Map)을 순회할 때 순서가 없다.
package main

import (
    "fmt"
    "strconv"
)

func main() {

    var exampleMap map[string]int
    exampleMap = make(map[string]int)

    // add
    exampleMap["Mike"] = 100
    exampleMap["John"] = 110
    exampleMap["Jennie"] = 120

    // delete
    delete(exampleMap, "John")

    fmt.Println(exampleMap["Mike"])
    fmt.Println()

    // map iteration
    for key, value := range exampleMap {
        fmt.Println(key, value)
    }
    fmt.Println()

    // check key exist
    val, exist := exampleMap["Jennie"]
    if exist {
        fmt.Println("exist! its value is " + strconv.Itoa(val))
    }

}
100

Mike 100
Jennie 120

exist! its value is 120


참고자료

Summarize about basice usage of Go.

This post assumes that reader already know about other computer languages. This is not for computer language beginner.


Environment and Prerequisite

  • Go(1.15.8)
  • Experience with other programming languages


Installation

Mac

$ go version
go version go1.15.8 darwin/amd64

Ubuntu

  • Download file
curl https://golang.org/dl/go1.15.8.linux-amd64.tar.gz -o go1.15.8.linux-amd64.tar.gz
  • Install file
sudo tar -C /usr/local -xzf go1.15.8.linux-amd64.tar.gz
  • Add /usr/local/go/bin to PATH environment variable
  • It it fine to use like below but I recommend add to ~/.bash_profile or ~/.bashrc.
export PATH=$PATH:/usr/local/go/bin


Build and Test

  • Skip project directory structure because this only for basic language usage.

Write Basic Code

test.go

package main

import "fmt"

func main() {
	fmt.Println("Hello, world!")
}

Build and Run

  • Run after build
$ go build test.go
$ ./test
Hello, world!
  • Also possible like below
$ go run test.go
Hello, world!


Usage

Basic Code Form

test.go

// package name
// every Go program is made up of packages
// programs start running in package main
package main

// import other packages
import "fmt"

// main function
// it is like "void main()" in C language
func main() {
	fmt.Println("Hello, world!")
}
Hello, world!


Variable Declaration

Characteristics

  • Declare var variable type(its form is different from others)
  • There is pointer.
  • It can be declared in various ways like below.
package main

import "fmt"

func main() {
	/*
	variable examples
	*/
	var i int
	i = 1

	var j = 2

	var a,b int
	a = 3
	b = 4

	x := 5

	fmt.Println(i, j, a, b, x)


	/*
	constant examples
	*/

	const c = 10
	const str = "string"

	// multiple constants
	const (
    	visa = "Visa"
    	master = "MasterCard"
    	amex = "American Express"
	)

	fmt.Println(c, str, visa, master, amex)


	/*
	pointer example
	*/

	var ptrVal int = 100
	var ptr *int = &ptrVal

	*ptr = 150

	fmt.Println(ptrVal, *ptr)
}
1 2 3 4 5
10 string Visa MasterCard American Express
150 150


Condition Statement - if

Characteristics

  • After if must be true or false not a number.
package main

import "fmt"

func main() {
    testVal := 10

    if testVal % 3 == 1 {
        fmt.Println("Remainder is 1")
    } else if testVal % 3 == 2 {
        fmt.Println("Remainder is 2")
    } else {
        fmt.Println("Remainder is 0")
    }
}
Remainder is 1


Condition Statement - switch

Characteristics

  • It breaks switch statement if one case statement is settled.
  • If use fallthrough, then it continues next case statement.
package main

import "fmt"

func main() {
	var name string
    var category = 2

    switch category {
    case 1:
        name = "Good"
    case 2:
        name = "Very Good"
    case 3, 4: // multiple value can be used in case
        name = "Super Nice"
    default:
        name = "Power"
    }
    fmt.Println(name)
}
Very Good


Iteration - for

Characteristics

  • There is no while statement and only for statement is exist. We can use for statement like while statement.
  • Also we can use continue and break like C language.
package main

import "fmt"

func main() {

	// basic form
	var sum int = 0

	for i := 1; i < 10; i++ {
		sum += i
	}
	fmt.Println(sum)


	// range usage with array
	names := []string {"김씨", "이씨", "박씨"}

	// index variable is index of array or slice
	for index, name := range names{
		fmt.Println(index, name)
	}


	// for statement with only condition
	sum = 0
	i := 0

	for i < 10 {
		sum += i
		i++
	}
	fmt.Println(sum)
}
45
0 김씨
1 이씨
2 박씨
45


Function

Characteristics

  • It can return multi values like python.
  • ‘Pass By Reference’ exists like C++.
package main

import "fmt"

func exampleFunc (msg string) {
	fmt.Println(msg)
}

func exampleFuncReturn (msg string) string{
	return msg
}

func exampleFuncReturnMultiple (first int, second int) (int, int){
	return first, second
}

func exampleFuncPassByReference (val *int){
	*val += 10
}

func main() {
	exampleFunc("exampleFunc test")

	fmt.Println(exampleFuncReturn("exampleFuncReturn test"))

	a,b := exampleFuncReturnMultiple(3, 4)
	fmt.Println(a, b)

	var testVal int = 100
	exampleFuncPassByReference(&testVal)
	fmt.Println(testVal)
}
exampleFunc test
exampleFuncReturn test
3 4
110


Anonymous Function

Characteristics

  • We can assign function to variable and also there anonymous function which does not have function name.
package main

import "fmt"

func main() {

    sum := func (values []int) int {
        res := 0
        for _, val := range values {
            res += val
        }
        return res
    }

    fmt.Println(sum([]int {1, 2, 3}))


    sum2 := func (values ... int) int {
        res := 0
        for _, val := range values {
            res += val
        }
        return res
    }

    fmt.Println(sum2(1, 2, 3))
}
6
6


Array

package main

import "fmt"

func printResult(values [3]int) {

    for _, val := range values{
        fmt.Println(val)
    }
    fmt.Println()
}

func main() {

    var arr1 [3]int
    arr1[0] = 1
    arr1[1] = 2
    // arr1[2] will be 0 it is default value

    var arr2 = [3] int {1, 2, 3}
    var arr3 = [...] int {1, 2, 3}

    printResult(arr1)
    printResult(arr2)
    printResult(arr3)
}
1
2
0

1
2
3

1
2
3

Slice

Characteristics

  • It is dynamic size array. It supports append, merge, copy and sub-slice.
package main

import "fmt"

func main() {

    var sliceExample []int   
    sliceExample = []int{1, 1, 1}
    // also same as below
    // sliceExample := make([]int, 3, 1)


    // append
    sliceExample = append(sliceExample, 2)
    sliceExample = append(sliceExample, 3, 4, 5)
    fmt.Println(sliceExample)
    fmt.Println()


    // append slices
    sliceExampleA := []int{1, 2, 3}
    sliceExampleB := []int{4, 5, 6}
    fmt.Println(append(sliceExampleA, sliceExampleB...))
    fmt.Println()


    // sub-slice
    sliceExample  = []int{1, 2, 3, 4, 5}
    fmt.Println(sliceExample[:]) // 1 2 3 4 5
    fmt.Println(sliceExample[2:]) // 3 4 5
    fmt.Println(sliceExample[:4]) // 1 2 3 4
    fmt.Println(sliceExample[2:4]) // 3 4
}
[1 1 1 2 3 4 5]

[1 2 3 4 5 6]

[1 2 3 4 5]
[3 4 5]
[1 2 3 4]
[3 4]


Map

Characteristics

  • There is no order in map iteration.
package main

import (
    "fmt"
    "strconv"
)

func main() {

    var exampleMap map[string]int
    exampleMap = make(map[string]int)

    // add
    exampleMap["Mike"] = 100
    exampleMap["John"] = 110
    exampleMap["Jennie"] = 120

    // delete
    delete(exampleMap, "John")

    fmt.Println(exampleMap["Mike"])
    fmt.Println()

    // map iteration
    for key, value := range exampleMap {
        fmt.Println(key, value)
    }
    fmt.Println()

    // check key exist
    val, exist := exampleMap["Jennie"]
    if exist {
        fmt.Println("exist! its value is " + strconv.Itoa(val))
    }

}
100

Mike 100
Jennie 120

exist! its value is 120


Reference