non-decreasing order

비내림차순 정렬. gpt가 설명해주기론 [1, 2, 2, 4] 를 비내림차순 정렬하면 2와 2의 순서가 고정되지만, 오름차순으로 정렬하면 순서가 바뀔 수도 있다고 한다.

 

The final sorted array should not be returned by the function,

num1 = nums1 + nums2

으로 했더니 입력값 그대로 [1,2,3,0,0,0]을 반환했다. 왜 안 됨? 하다가 function 쓰지 말라고 해서 그런가 했다

 

 

class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """
        i = m - 1
        j = n - 1        
        for p in reversed(range(len(nums1))):
            if(j == -1 and i == -1):
                break
            elif(i == -1):
                nums1[p] = nums2[j]
                j -= 1
            elif(j == -1):
                nums1[p] = nums1[i]
                i -= 1
            elif(nums1[i] <= nums2[j]):
                nums1[p] = nums2[j]
                j = j - 1
            else:
                nums1[p] = nums1[i]
                nums1[i] = 0
                i = i - 1
class Solution:
    def merge_gpt(self, nums1, m, nums2, n):
        """
        :type nums1: List[int]
        :type m: int
        :type nums2: List[int]
        :type n: int
        :rtype: None Do not return anything, modify nums1 in-place instead.
        """
        # nums1 배열의 끝 인덱스
        end = m + n - 1
        
        # nums1 배열과 nums2 배열을 뒤에서부터 비교하여 큰 수를 nums1 배열의 끝에서부터 채워넣음
        while m > 0 and n > 0:
            if nums1[m-1] > nums2[n-1]:
                nums1[end] = nums1[m-1]
                m -= 1
            else:
                nums1[end] = nums2[n-1]
                n -= 1
            end -= 1
        
        # nums1 배열이 비어있을 경우, nums2 배열의 나머지 요소들을 nums1 배열에 복사함
        if n > 0:
            nums1[:n] = nums2[:n]
        print(nums1)

 

보이기에는 gpt가 만든 코드가 깔끔한데 성능은 내가 만든 것이 조금 더 낫다. 왜인지는 모르겠다. 코딩은 어렵다.

000. 2750번: 수 정렬하기

더보기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>

using namespace std;

int main() {
	int arr[1000];
	int n;
	unsigned int sum = 0;

	scanf("%d", &n);

	for (int i = 0; i < n; i++) {
		scanf("%1d", &arr[i]);
		sum += arr[i];
	}

	cout << sum << endl;

}

001. 11720번 숫자의 합

더보기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>

// using namespace std;

int main() {
	int arr[1000];
	int n;
	
	scanf("%d", &n);

	for (int i = 0; i < n; i++) {
		scanf("%d", &arr[i]);
	}

	for (int i = 0; i < n-1; i++) {
		for (int j = i+1; j < n; j++) {
			if (arr[i] > arr[j]) {
				int tmp;

				tmp = arr[i];
				arr[i] = arr[j];
				arr[j] = tmp;
			}
		}
		
	}
	for (int i = 0; i < n; i++) {
		std::cout << arr[i] << std::endl;
	}

}

 

002. 1546번: 평균

더보기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>

using namespace std;

float new_score_func(int a, int max1);

int main() {
	int n;

	int arr[1000];
	float new_score[1000];
	
	float sum = 0;

	scanf("%d", &n);	// 과목 갯수 n <=1000
	
	int max = -1;

	for (int i = 0; i < n; i++) {
		scanf("%d", &arr[i]);

		if (max < arr[i]) max = arr[i];
	}

	for (int i = 0; i < n; i++) {
		int tmp = arr[i];

		new_score[i] = new_score_func(tmp, max);

		sum += new_score[i];
	}
	
	// 출력 부
	 float result = sum / n;

	cout << sum / n << endl;

	//////////////////////////////

	//for (int i = 0; i < n; i++) {
	//	printf("%d ", arr[i]);
	//}

	//for (int i = 0; i < n; i++) {
	//	printf("%f ", new_score[i]);
	//}
	//printf("\n ");
	//cout << "max= "<< max << endl;


}

float new_score_func(int a, int max1) {
	float score;

	score =(float) a  / max1 * 100;

	return score;
}

003. 11659번: 구간 합 구하기

더보기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>

using namespace std;

int sum_arr[100001] = { 0, };

int main() {
	int n, m;
	
	scanf("%d %d", &n, &m);	// 수의 갯수, 합의 갯수

	for (int i = 0; i < n; i++) {
		int num;
		scanf("%d", &num);
		sum_arr[i + 1] = sum_arr[i] + num;
	}

	for (int i = 0; i < m; i++) {
		int a, b;
		scanf("%d %d", &a, &b);

		// printf("%d\n", sum_arr[b] - sum_arr[a - 1]);
		cout << sum_arr[b] - sum_arr[a - 1] << '\n' ;
	}

}

11659번은 출력할 때 \n이 없으면 틀렸다고 판단하는듯 하다.

또한, '\n'대신 endl을 사용하면 틀리다고 나온다. 백준에 검색할 경우, endl은 버퍼를 비워야해서 느리고,

백준에서는 시간까지 체크하기 때문에 틀렸다고 판단한다고 한다.

https://www.acmicpc.net/board/view/5984

 

글 읽기 - \n과 endl이 다른가요?

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

 

15662번 톱니바퀴 (2)  71.87%

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>
#include <vector>
#include <stdbool.h>
#include <iostream>

using namespace std;

void rot_right(); void rot_left();

int gear[1000][8];
int gear_tmp[8];
int right_gear, left_gear;


int main() {
	int gear_num; // 톱니바퀴 갯수
	int rot_num; // 회전 횟수
	int a;
	
	// vector<vector<int>> v;

	scanf("%d", &gear_num);	// 기어 갯수 입력 

	// 톱니바퀴 세팅
	for (int i = 0; i < gear_num; i++) {
		scanf("%d", &a);	// 기어 N극, S극 받음
		for (int j = 0; j < 8;j++) {
			gear[i][7 - j] = a % 10;
			a = a / 10;
		}
	}

	scanf("%d", &rot_num);	// 회전 횟수 입력 

	// 0. 회전 반복
	for (int i = 0; i < rot_num; i++) {
		int pick;	// 선택 기어
		int dir; // 시계: 1, 반시계: -1				
		
		scanf("%d %d", &pick, &dir);
		int pick_gear= pick-1; // 선택 기어의 배열

		// 0. 회전 범위 체크
		// 0-1. 픽업 기준 왼쪽 체크
		left_gear = 0;
		for (int k = pick_gear; (left_gear == 0) && (k > 0); k--) {
			// k=1 일 때의 예외처리
			if (k == 1) {
				if (gear[0][2] != gear[k][6]) {
					left_gear = 0;
				}
				else left_gear = 1;
			}
			// 왼쪽 톱니바퀴의 극성이 같을 경우
			else if (gear[k - 1][2] == gear[k][6]) {
				left_gear = k;
			}
			// 다르면 계속 진행
		}
		// 0-2. 오른쪽 체크
		right_gear = gear_num-1;
		for (int k = pick_gear; (right_gear == gear_num-1) && (k < gear_num-1); k++) {
			// 가장 오른쪽 톱니 비교
			if (k == gear_num-2) {
				if (gear[k][2] != gear[gear_num-1][6]) {
					right_gear = gear_num-1;
				}
				else right_gear = k;
			}
			// 극성이 같을 경우
			else if (gear[k][2] == gear[k + 1][6]) {
				right_gear = k;
			}
			// 왼쪽 톱니바퀴의 극성이 다를 경우	
			
		}
		// 1. 회전
		// 1-1. 우회전을 대입했을 때
		if (dir == 1) {
			for (int k = left_gear; k <= right_gear; k++) {
				// 한 행 = 기어 복사
				for (int j = 0; j < 8; j++) {
					gear_tmp[j] = gear[k][j];
				}
				// 좌, 우 회전
				if (abs(k - pick_gear) % 2 == 0) {
					rot_right();
				}
				else  {
					rot_left();
				}
				// 다시 대입
				for (int j = 0; j < 8; j++) {
					gear[k][j] = gear_tmp[j];
				}
			}
		}
		// 1-2. 좌회전을 대입했을 때
		else if (dir == -1) {
			for (int k = left_gear; k <= right_gear; k++) {
				// 한 행 = 기어 복사
				for (int j = 0; j < 8; j++) {
					gear_tmp[j] = gear[k][j];
				}
				// 좌, 우 회전
				if (abs(k - pick_gear) % 2 == 0) {
					rot_left();
				}
				else {
					rot_right();
				}
				// 다시 대입
				for (int j = 0; j < 8; j++) {
					gear[k][j] = gear_tmp[j];
				}
			}
		}	// 좌회전, 우회전 END
	}	// 회전 반복 END

	// 2. S극(1) 카운팅
	int cnt = 0;
	for (int i = 0; i < gear_num; i++) {
		if (gear[i][0]) {
			cnt++;
		}
	}
	printf("%d", cnt);
	////////////////////////////////

	/*printf("\n디버깅");
	printf("왼쪽= %d, 오른쪽= %d\n", left_gear, right_gear);
	printf("바뀐 톱니\n");
	for (int k = 0; k < gear_num; k++) {
		for (int i = 0; i < 8; i++) {
			if (gear[k][i] == 1) {
				printf("1");
			}
			else {
				printf("0");
			}
		}
		printf("\n");
	}*/

}

void rot_right() {
	bool tmp = gear_tmp[7];
	for (int i = 7; i >= 1; i--) {
		gear_tmp[i] = gear_tmp[i - 1];
	}
	gear_tmp[0] = tmp;
}
void rot_left() {
	bool tmp = gear_tmp[0];
	for (int i = 0; i <= 6; i++) {
		gear_tmp[i] = gear_tmp[i + 1];
	}
	gear_tmp[7] = tmp;
}

*웹서버와 WAS 연동방식

1. ISAPI

단점: 속도 느리다 회사가 다른 제품일 때 보통 쓴다

2. 라이브러리

같은 회사 것만 사용 가능(아파치-톰캣 등) 속도가 빠르다

 

 

0. 웹서버와 WAS 비교


서버 웹서버 WAS(Web Application Server)

프로그램 아파치 톰캣
포트 80 8080
  정적 동적

1. 아파치-톰캣 연동 설명


참고 사이트

AJP, mod_jk 설명 사이트

https://noobnim.tistory.com/26

아파치, 톰캣 설명 참고 사이트

https://byul91oh.tistory.com/65

1-1. APJ, mod_jk

(1) APj

웹서버 뒤에 있는 어플리케이션 서버로부터 웹서버로 들어오늘 요청을 위임할 수 있는 바이너리 프로토콜이다.

(2) mod_jk

아파치, 톰캣 연동을 위해 mod_jk 라는 모듈을 사용하는데, 이는 AJP프로토콜을 사용하여 톰캣과 연동하기 위해 만들어진 모듈이다. mod_jk는 톰캣의 일부로 배포되지만, 아파치 웹서버에 설치하여야 한다.

1-2. 동작 방식

https://madplay.github.io/post/apache-tomcat-modjk

 

  1. 아파치 웹서버의 httpd.conf에 톰캣 연동을 위한 설정을 추가하고 톰캣에서 처리할 요청을 지정한다.
  2. 사용자의 브라우저는 아파치 웹서버(보통 포트80)에 접속해 요청한다.
  3. 아파치 웹서버는 사용자의 요청이 톰캣에서 처리하도록 지정된 요청인지 확인 후, 톰캣에서 처리해야 하는 경우 아파치 웹서버는 톰캣의 AJP포트(보통 8009포트)에 접속해 요청을 전달한다.
  4. 톰캣은 아파치 웹서버로부터 요청을 받아 처리한 후, 처리 결과를 아파치 웹서버에 되돌려 준다.
  5. 아파치 웹서버는 톰캣으로부터 받은 처리 결과를 사용자에게 전송한다. 출처: https://noobnim.tistory.com/26 [공부하는 블로그:티스토리]

2. 아파치와 톰캣 연동 설정


참고 사이트

아파치 톰캣 연동하기(apache, tomcat, mod_jk)

아파치 톰캣 연동

2-1. Apache 설정하기

(1) 라이브러리 다운 및 폴더 디렉토리 설정

라이브러리 다운

https://www.apachelounge.com/download/ 에서 다운로드 파일 다운

zip 파일 안의 mod_jk.so 파일을 $Apache_Home > modules 폴더 안에 위치시킴

(2) workers.properties 추가

 

📢 workers.properties 파일은 Apache HTTP Server에서 연결하고자 하는 Tomcat에 대한 정의 및 설정 파일이다. workers는 back-end에 위치한 각 Tomcat 인스턴스들을 가리킨다.

[worker.properties 설명 출처]

(https://sarc.io/index.php/httpd/259-workers-properties-1#:~:text=이 workers.properties 파일은,정의 및 설정 파일이다.&text=worker.tomcat1%2C worker.tomcat2,값과 동일해야 한다.)

[Apache_Home] > conf 폴더에 텍스트 파일을 생성한다. 텍스트 파일을 [worker.properties] 이라고 제목을 수정하고 다음의 코드를 추가한다.

  • worker.properties 추가 코드
worker.list=study
worker.study.type=ajp13
worker.study.host=localhost
worker.study.port=8009

(3) AJP 옵션 활성화

$Apace_Home > conf 폴더의 httpd.conf파일에서 AJP 옵션을 활성화 해야 한다.

맨 아래에 다음의 코드를 추가한다 (아마도 한글 설정하는 코드 아래일 것임 )

  • httpd.conf 수정 코드 (AJP 옵션 활성화)
#mod_jk 모듈 설정
     LoadModule jk_module modules/mod_jk.so
     JkworkersFile conf/workers.properties
     JkMount /* study
 # log 파일 만들기
     JkLogFile logs/mod_jk.log
     JkLogLevel info
     JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
     JkRequestLogFormat "%w %V %T"

2-2. 톰캣 설정하기

(1) AJP 활성화

%Tomcat_Home > conf 폴더에서 server.xml 파일을 수정한다.

주석 처리되있다면 해제하고, 포트 등이 맞는지 확인 한다

  • server.xml 코드
<!-- Define an AJP 1.3 Connector on port 8009 -->

    <Connector protocol="AJP/1.3"
               address="127.0.0.1"
               port="8009"
               redirectPort="8443"
	secretRequired="false"
    />

2-3. 가상 호스트 설정

📢 동일한 서버 내에 여러 도메인을 가진 웹서버를 구축해서 서비스를 할 때 사용
www.plc1.com
www.plc2.com 등
아파치 입장에서는 톰캣이 가상 호스트임

[Apache_Home]\conf\extra\httpd-vhosts.conf 에 다음의 코드 추가

<VirtualHost *:8009>    
      ServerAdmin admin    
      DocumentRoot "C:/webroot"
      ErrorLog "logs/example-project-error.log"
      CustomLog "logs/example-project-access.log"
</VirtualHost>

3. 결과

*** MachineInfo.java 파일의 서브렛을 ("/dbconnection")으로 바꾼 상태임(컴파일도 해둠)

톰캣, 아파치 서버를 전부 끄고, 톰캣 → 아파치 순서대로 실행한다. (아파치는 윈도우 서비스이므로 관리자 권한 실행)

이후에는 포트번호(8080)이 없이 서브렛만 입력해도 된다.

http://127.0.0.1/dbconnection

속도가 빠르다

 

'JAVA > 웹서버' 카테고리의 다른 글

아파치 Servlet 만들기  (0) 2022.05.30
아파치 톰캣 만들기  (0) 2022.05.27
아파치 서버 만들기  (0) 2022.05.27

1. 플라스틱 배출

 

 

 

2. 금속배출

 

 

MPS 트레이너를 이용하여 시퀀스 제어를 실습함

29.2) 적외선 데이터 포맷

적외선을 통해 데이터를 전달하기 위해서는 데이터를 펄스열로 바꾸어야 한다. 데이터를 펄스열로 바꾸는 방법에는 여러 가지가 있는데, 흔히 NEC 프로토콜을 사용한다.

NEC 프로토콜

NEC 프로토콜은 펄스 거리 인코딩(pulse idstancce encoding) 방식을 사용한다.

위와 같이 펄스 거리로 0과 1을 표현한다.

1은 0의 3배의 LOW 값을 전송한다.

데이터 시작 표시 신호

데이터의 시작 표시하는 신호는 두 가지로 일반 데이터, 반복 데이터로 나뉘어져 있다.

9ms의 HIGH 값을 동일하나, LOW 값이 각각 4.5ms, 2.25ms로 다르다.

NEC 프로토콜을 사용한 리모컨의 데이터 신호

리드 코드 → 커스텀 코드 → 반전 커스텀 코드 → 데이터 코드 → 반전 데이터 코드

커스텀 코드는 특정 회사임을 알려준다.

0과 1의 길이는 다르지만, 반전된 신호를 보내줌으로써 전체 신호의 길이는 일정하다.

반복된 신호의 경우 리드 코드의 반복 데이터가 110ms으로 전송된다.

29.3) 적외선 데이터 디코딩

NEC 프로토콜의 경우, 시간 간격을 통하여 데이터를 구분할 수 있다. 따라서 시간 간격(clock, TCNT reg)을 이용하여 디코딩할 수 있다.

다음의 코드는 16 MHz를 1024 분주비로 사용한 것이다. 따라서 15625 Hz로 작동하고 1 clock 당 64us의 시간이 걸린다. 데이터에 따라 TCNT 값이 달라지도록 코딩했고, TCNT 값이 저장된 변수 time에 따라 데이터를 판단하도록 했다.

0과 1을 나누는 조건으로 (26 초과, 나머지)를 사용했다. 논리 0과 1이 각각 18 클록, 35 클록이므로 중간값을 기준으로 작으면 0으로, 크면 1로 처리했다.

 

'MCU > ATmega128a' 카테고리의 다른 글

13. 8 bit 타이머  (0) 2022.06.02
14. 16 bit 타이머/카운터  (0) 2022.06.02

아트메가128의 8 bit 타이머/카운터 블록의 다이어그램은 다음과 같다

13.2 오버플로 인터럽트

TCNTn(n=0, 2) REG (Timer/Counter Regitser)

8 bit 레지스터로 2^8 -1 까지 셀 수 있다. 255가 넘어가면 0으로 오버플로우 한다. *비교 일치 인터럽트의 경우, 자동으로 초기화되지 않아 ‘TCNTn =0’ 처럼 따로 초기화를 해야 한다.

비활성화 상태가 디폴트이며 TCCRn Reg의 CS0 bit를 조작하여 활성화할 수 있다.

  • TCCR reg (Timer/Counter Control Register)
    • 7번 bit 의 경우, Force Output Compare 으로 세트될 경우 , 비교 일치가 발생한 것과 동일한 효과가 파형 출력핀 OC에 출력된다

TIMSK reg (Timer/Counter Interrupt Mask Register)

0, 1, 6, 7 bit 를 조작하여 각각 0번, 2번 타이머/카운터의 Interrupt를 Enable, disable 할 수 있다.

OCIEn = Timer/Counter Output Compare Match Interrupt Enable TOIEn = Timer/Counter Overflow Interrupt Enable

TIFR(Timer/Counter Interrupt Flag Register)

그림 13-6.

OCFn = Ouput Compare Flag TOVn = Timer/Counter Overflow Flag

오버플로우, 비교 일치의 조건을 만족할 경우 해당하는 bit 가 세트되고, TIMSK의 해당 비트도 세트된 경우 인터럽트를 발생시킨다.

인터럽트 벡터 이름

main 함수 위에 ISR(”인터럽트 벡터 이름”) { 실행 내용} 식으로 사용한다.

13.3 비교 일치 인터럽트

OCRn reg (Output Compare Register)

*비교 인터럽트를 사용하기 위해서는 먼저 OCR reg 에 비교값을 설정해야 한다.

그림 13-7

비교 일치가 발생하는 경우 지정된 핀 외에도 지정된 핀을 통해 신호를 출력하는 것이 가능하다.

13.4 파형 출력

Timer/Counter 1번의 비교 일치 C와 Timer/Counter 2번의 비교 일치의 경우 동일하게 Port B 7 을 사용하는 것을 유의

TCCR0 register

bit 7의 FOC0의 경우, 쓰기 전용 비트로써 1이 세트될 경우 비교 출력이 일어난 것과 동일한 효과를 가져온다.

WGM (Waveform Generator mode) Bit

 

WGM Bit는 어떤 파형을 생성할지 결정한다

COM (Compare Match Output)

비교 일치 출력 모드를 설정한다.

WGM에 따라 달라지지만 정상 모드와 CTC 모드의 경우는 동일하다.

13.5 ASSR reg (Asynchronous Status Register)

외부 클릭에 의하여 비동기 모드로 동작하는 경우에 관련된 기능을 수행한다

'MCU > ATmega128a' 카테고리의 다른 글

29. 적외선 통신  (0) 2022.06.07
14. 16 bit 타이머/카운터  (0) 2022.06.02

타이머를 이용하여 1초마다 인터럽트 하는 코드

#include <avr/io.h>
#include <avr/interrupt.h>

int state = 0;

ISR(TIMER1_OVF_vect){
	TCNT1H = 0xC2;
	TCNT1L = 0x4C;
	state = !state;
}
int main(void)
{
   DDRB = 0x01;
   PORTB = 0x00;
   
   TCCR1B |= (1 << CS12) | (1 << CS10);		// 1024 분주 
   TIMSK |= (1 << TOIE1);
   
   TCNT1H = 0xC2;
   TCNT1L = 0x4C;
   
   sei();
   
    while (1)    {
    if(state) PORTB = 0x01;
	else PORTB = 0x00;
	}
	return 0;
	
}

14.1) 16비트 타이머/카운터

16 비트 타이머/카운터 구조

그림 14-1

14.2) 오버플로 인터럽트

TCNTn (n= 1,3) register

TCCR1B register

분주비 설정(TCNT reg 활성화), 입력 캡처, 파형생성 비트 등이 있다.

WGM의 경우, TCCR1A의 WGM10, WGM11까지 합쳐 4 bit 로 컨트롤한다.

CS1n (n=0, 1, 2) Bit

제목의 CS0n 은 CS1n의 오타이다

TIMSK register

2번 비트는 오버플로

3, 4 bit = A, B 비교 출력

5 bit = 입력 캡처

비교 일치 Interrupt PIN

ETIMSK register

1번 T/C 비교 출력 C 인터럽트

TIFR register

오버플로 인터럽트의 조건을 만족하면 TIFR reg의 해당 bit가 세트된다. 해당 비트가 세트된 상태에서 TIMSK의 해당 bit도 세트 되어있다면 인터럽트가 발생된다.

ETIFR register

1번 타이머/카운터 관련 인터럽트

ISR(”벡터 이름”) { 인터럽트 내용 } 으로 사용함

14.3) 비교 일치 인터럽트

OCR1x (x= A, B ,C) register

 

14.4) 파형 출력

비교 일치 인터럽트 시 파형 출력 핀

표 14-4.

TCCR1A register

TCCR1B register

WGM1n (n= 0, 1, 2, 3) 은 TCCR1A & B에 나눠져 있으며 4 bit 로 출력 파형을 결정

WGMn (n= 0, 1, 2, 3) Bit

COM1An (n= 0, 1) Bit

PWM 모드 이외의 경우에는 다음과 같이 일치 출력 모드를 결정한다

TCCR1C register

FOC1x Bit 는 일회성으로 필요할 때마다 1을 세트해야 한다. 쓰기 전용이지만 읽기를 했을 경우 0을 반환한다.

14.5) 입력 캡처

ICRn (n = 1, 3) register

14.6) 요약

'MCU > ATmega128a' 카테고리의 다른 글

29. 적외선 통신  (0) 2022.06.07
13. 8 bit 타이머  (0) 2022.06.02

+ Recent posts