Skip to content

Commit 599c9b5

Browse files
committed
feat: add solutions to lc problem: No.1116
No.1116.Print Zero Even Odd
1 parent 7ef911b commit 599c9b5

File tree

5 files changed

+308
-40
lines changed

5 files changed

+308
-40
lines changed

solution/1100-1199/1116.Print Zero Even Odd/README.md

+127-1
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,148 @@
6060

6161
<!-- 这里可写通用的实现逻辑 -->
6262

63+
**方法一:多线程 + 信号量**
64+
65+
我们用三个信号量 $z$, $e$, $o$ 来控制三个线程的执行顺序,其中 $z$ 的初始值为 $1$,$e$ 和 $o$ 的初始值为 $0$。
66+
67+
- 信号量 $x$ 控制 `zero` 函数的执行,当 $z$ 信号量的值为 $1$ 时,`zero` 函数可以执行,执行完毕后将 $z$ 信号量的值设为 $0$,并将 $e$ 信号量的值设为 $1$ 或 $o$ 信号量的值设为 $1$,具体取决于下一次需要执行的是 `even` 函数还是 `odd` 函数。
68+
- 信号量 $e$ 控制 `even` 函数的执行,当 $e$ 信号量的值为 $1$ 时,`even` 函数可以执行,执行完毕后将 $z$ 信号量的值设为 $1$,并将 $e$ 信号量的值设为 $0$。
69+
- 信号量 $o$ 控制 `odd` 函数的执行,当 $o$ 信号量的值为 $1$ 时,`odd` 函数可以执行,执行完毕后将 $z$ 信号量的值设为 $1$,并将 $o$ 信号量的值设为 $0$。
70+
71+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。
72+
6373
<!-- tabs:start -->
6474

6575
### **Python3**
6676

6777
<!-- 这里可写当前语言的特殊实现逻辑 -->
6878

6979
```python
70-
80+
from threading import Semaphore
81+
82+
class ZeroEvenOdd:
83+
def __init__(self, n):
84+
self.n = n
85+
self.z = Semaphore(1)
86+
self.e = Semaphore(0)
87+
self.o = Semaphore(0)
88+
89+
# printNumber(x) outputs "x", where x is an integer.
90+
def zero(self, printNumber: 'Callable[[int], None]') -> None:
91+
for i in range(self.n):
92+
self.z.acquire()
93+
printNumber(0)
94+
if i % 2 == 0:
95+
self.o.release()
96+
else:
97+
self.e.release()
98+
99+
def even(self, printNumber: 'Callable[[int], None]') -> None:
100+
for i in range(2, self.n + 1, 2):
101+
self.e.acquire()
102+
printNumber(i)
103+
self.z.release()
104+
105+
def odd(self, printNumber: 'Callable[[int], None]') -> None:
106+
for i in range(1, self.n + 1, 2):
107+
self.o.acquire()
108+
printNumber(i)
109+
self.z.release()
71110
```
72111

73112
### **Java**
74113

75114
<!-- 这里可写当前语言的特殊实现逻辑 -->
76115

77116
```java
117+
class ZeroEvenOdd {
118+
private int n;
119+
private Semaphore z = new Semaphore(1);
120+
private Semaphore e = new Semaphore(0);
121+
private Semaphore o = new Semaphore(0);
122+
123+
public ZeroEvenOdd(int n) {
124+
this.n = n;
125+
}
126+
127+
// printNumber.accept(x) outputs "x", where x is an integer.
128+
public void zero(IntConsumer printNumber) throws InterruptedException {
129+
for (int i = 0; i < n; ++i) {
130+
z.acquire(1);
131+
printNumber.accept(0);
132+
if (i % 2 == 0) {
133+
o.release(1);
134+
} else {
135+
e.release(1);
136+
}
137+
}
138+
}
139+
140+
public void even(IntConsumer printNumber) throws InterruptedException {
141+
for (int i = 2; i <= n; i += 2) {
142+
e.acquire(1);
143+
printNumber.accept(i);
144+
z.release(1);
145+
}
146+
}
147+
148+
public void odd(IntConsumer printNumber) throws InterruptedException {
149+
for (int i = 1; i <= n; i += 2) {
150+
o.acquire(1);
151+
printNumber.accept(i);
152+
z.release(1);
153+
}
154+
}
155+
}
156+
```
78157

158+
### **C++**
159+
160+
```cpp
161+
#include <semaphore.h>
162+
163+
class ZeroEvenOdd {
164+
private:
165+
int n;
166+
sem_t z, e, o;
167+
168+
public:
169+
ZeroEvenOdd(int n) {
170+
this->n = n;
171+
sem_init(&z, 0, 1);
172+
sem_init(&e, 0, 0);
173+
sem_init(&o, 0, 0);
174+
}
175+
176+
// printNumber(x) outputs "x", where x is an integer.
177+
void zero(function<void(int)> printNumber) {
178+
for (int i = 0; i < n; ++i) {
179+
sem_wait(&z);
180+
printNumber(0);
181+
if (i % 2 == 0) {
182+
sem_post(&o);
183+
} else {
184+
sem_post(&e);
185+
}
186+
}
187+
}
188+
189+
void even(function<void(int)> printNumber) {
190+
for (int i = 2; i <= n; i += 2) {
191+
sem_wait(&e);
192+
printNumber(i);
193+
sem_post(&z);
194+
}
195+
}
196+
197+
void odd(function<void(int)> printNumber) {
198+
for (int i = 1; i <= n; i += 2) {
199+
sem_wait(&o);
200+
printNumber(i);
201+
sem_post(&z);
202+
}
203+
}
204+
};
79205
```
80206
81207
### **...**

solution/1100-1199/1116.Print Zero Even Odd/README_EN.md

+117-1
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,129 @@ One of them calls zero(), the other calls even(), and the last one calls odd().
6161
### **Python3**
6262

6363
```python
64-
64+
from threading import Semaphore
65+
66+
class ZeroEvenOdd:
67+
def __init__(self, n):
68+
self.n = n
69+
self.z = Semaphore(1)
70+
self.e = Semaphore(0)
71+
self.o = Semaphore(0)
72+
73+
# printNumber(x) outputs "x", where x is an integer.
74+
def zero(self, printNumber: 'Callable[[int], None]') -> None:
75+
for i in range(self.n):
76+
self.z.acquire()
77+
printNumber(0)
78+
if i % 2 == 0:
79+
self.o.release()
80+
else:
81+
self.e.release()
82+
83+
def even(self, printNumber: 'Callable[[int], None]') -> None:
84+
for i in range(2, self.n + 1, 2):
85+
self.e.acquire()
86+
printNumber(i)
87+
self.z.release()
88+
89+
def odd(self, printNumber: 'Callable[[int], None]') -> None:
90+
for i in range(1, self.n + 1, 2):
91+
self.o.acquire()
92+
printNumber(i)
93+
self.z.release()
6594
```
6695

6796
### **Java**
6897

6998
```java
99+
class ZeroEvenOdd {
100+
private int n;
101+
private Semaphore z = new Semaphore(1);
102+
private Semaphore e = new Semaphore(0);
103+
private Semaphore o = new Semaphore(0);
104+
105+
public ZeroEvenOdd(int n) {
106+
this.n = n;
107+
}
108+
109+
// printNumber.accept(x) outputs "x", where x is an integer.
110+
public void zero(IntConsumer printNumber) throws InterruptedException {
111+
for (int i = 0; i < n; ++i) {
112+
z.acquire(1);
113+
printNumber.accept(0);
114+
if (i % 2 == 0) {
115+
o.release(1);
116+
} else {
117+
e.release(1);
118+
}
119+
}
120+
}
121+
122+
public void even(IntConsumer printNumber) throws InterruptedException {
123+
for (int i = 2; i <= n; i += 2) {
124+
e.acquire(1);
125+
printNumber.accept(i);
126+
z.release(1);
127+
}
128+
}
129+
130+
public void odd(IntConsumer printNumber) throws InterruptedException {
131+
for (int i = 1; i <= n; i += 2) {
132+
o.acquire(1);
133+
printNumber.accept(i);
134+
z.release(1);
135+
}
136+
}
137+
}
138+
```
70139

140+
### **C++**
141+
142+
```cpp
143+
#include <semaphore.h>
144+
145+
class ZeroEvenOdd {
146+
private:
147+
int n;
148+
sem_t z, e, o;
149+
150+
public:
151+
ZeroEvenOdd(int n) {
152+
this->n = n;
153+
sem_init(&z, 0, 1);
154+
sem_init(&e, 0, 0);
155+
sem_init(&o, 0, 0);
156+
}
157+
158+
// printNumber(x) outputs "x", where x is an integer.
159+
void zero(function<void(int)> printNumber) {
160+
for (int i = 0; i < n; ++i) {
161+
sem_wait(&z);
162+
printNumber(0);
163+
if (i % 2 == 0) {
164+
sem_post(&o);
165+
} else {
166+
sem_post(&e);
167+
}
168+
}
169+
}
170+
171+
void even(function<void(int)> printNumber) {
172+
for (int i = 2; i <= n; i += 2) {
173+
sem_wait(&e);
174+
printNumber(i);
175+
sem_post(&z);
176+
}
177+
}
178+
179+
void odd(function<void(int)> printNumber) {
180+
for (int i = 1; i <= n; i += 2) {
181+
sem_wait(&o);
182+
printNumber(i);
183+
sem_post(&z);
184+
}
185+
}
186+
};
71187
```
72188
73189
### **...**
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
1+
#include <semaphore.h>
2+
13
class ZeroEvenOdd {
24
private:
35
int n;
4-
int flag;
5-
mutex m1, m2, m3;
6+
sem_t z, e, o;
67

78
public:
89
ZeroEvenOdd(int n) {
910
this->n = n;
10-
flag = 1; //奇偶判断
11-
m1.lock();
12-
m2.lock();
13-
m3.lock();
11+
sem_init(&z, 0, 1);
12+
sem_init(&e, 0, 0);
13+
sem_init(&o, 0, 0);
1414
}
1515

1616
// printNumber(x) outputs "x", where x is an integer.
1717
void zero(function<void(int)> printNumber) {
18-
m3.unlock();
19-
for (int i = 0; i < n; i++) {
20-
m3.lock();
18+
for (int i = 0; i < n; ++i) {
19+
sem_wait(&z);
2120
printNumber(0);
22-
if (flag == 1)
23-
flag = 0, m2.unlock();
24-
else
25-
flag = 1, m1.unlock();
21+
if (i % 2 == 0) {
22+
sem_post(&o);
23+
} else {
24+
sem_post(&e);
25+
}
2626
}
2727
}
2828

29-
void odd(function<void(int)> printNumber) { //输出奇数
30-
for (int i = 1; i <= n; i += 2) {
31-
m2.lock();
29+
void even(function<void(int)> printNumber) {
30+
for (int i = 2; i <= n; i += 2) {
31+
sem_wait(&e);
3232
printNumber(i);
33-
m3.unlock();
33+
sem_post(&z);
3434
}
3535
}
3636

37-
void even(function<void(int)> printNumber) { //输出偶数
38-
for (int i = 2; i <= n; i += 2) {
39-
m1.lock();
37+
void odd(function<void(int)> printNumber) {
38+
for (int i = 1; i <= n; i += 2) {
39+
sem_wait(&o);
4040
printNumber(i);
41-
m3.unlock();
41+
sem_post(&z);
4242
}
4343
}
4444
};

0 commit comments

Comments
 (0)